@@ -1298,16 +1298,27 @@ pub fn GetFinalPathNameByHandle(
12981298 },
12991299 .Dos = > {
13001300 // parse the string to separate volume path from file path
1301- const expected_prefix = std .unicode .utf8ToUtf16LeStringLiteral ("\\ Device\\ " );
1302-
1303- // TODO find out if a path can start with something besides `\Device\<volume name>`,
1304- // and if we need to handle it differently
1305- // (i.e. how to determine the start and end of the volume name in that case)
1306- if (! mem .eql (u16 , expected_prefix , final_path [0.. expected_prefix .len ])) return error .Unexpected ;
1301+ const device_prefix = std .unicode .utf8ToUtf16LeStringLiteral ("\\ Device\\ " );
1302+
1303+ // We aren't entirely sure of the structure of the path returned by
1304+ // QueryObjectName in all contexts/environments.
1305+ // This code is written to cover the various cases that have
1306+ // been encountered and solved appropriately. But note that there's
1307+ // no easy way to verify that they have all been tackled!
1308+ // (Unless you, the reader knows of one then please do action that!)
1309+ if (! mem .startsWith (u16 , final_path , device_prefix )) {
1310+ // Wine seems to return NT namespaced paths starting with \??\ from QueryObjectName
1311+ // (e.g. `\??\Z:\some\path\to\a\file.txt`), in which case we can just strip the
1312+ // prefix to turn it into an absolute path.
1313+ return ntToWin32Namespace (final_path , out_buffer ) catch | err | switch (err ) {
1314+ error .NotNtPath = > return error .Unexpected ,
1315+ error .NameTooLong = > | e | return e ,
1316+ };
1317+ }
13071318
1308- const file_path_begin_index = mem .indexOfPos (u16 , final_path , expected_prefix .len , &[_ ]u16 {'\\ ' }) orelse unreachable ;
1319+ const file_path_begin_index = mem .indexOfPos (u16 , final_path , device_prefix .len , &[_ ]u16 {'\\ ' }) orelse unreachable ;
13091320 const volume_name_u16 = final_path [0.. file_path_begin_index ];
1310- const device_name_u16 = volume_name_u16 [expected_prefix .len .. ];
1321+ const device_name_u16 = volume_name_u16 [device_prefix .len .. ];
13111322 const file_name_u16 = final_path [file_path_begin_index .. ];
13121323
13131324 // MUP is Multiple UNC Provider, and indicates that the path is a UNC
0 commit comments