| ... | @@ -1298,16 +1298,27 @@ pub fn GetFinalPathNameByHandle( | ... | @@ -1298,16 +1298,27 @@ pub fn GetFinalPathNameByHandle( |
| 1298 | }, | 1298 | }, |
| 1299 | .Dos => { | 1299 | .Dos => { |
| 1300 | // parse the string to separate volume path from file path | 1300 | // parse the string to separate volume path from file path |
| 1301 | const expected_prefix = std.unicode.utf8ToUtf16LeStringLiteral("\\Device\\"); | 1301 | const device_prefix = std.unicode.utf8ToUtf16LeStringLiteral("\\Device\\"); |
| 1302 | | 1302 | |
| 1303 | // TODO find out if a path can start with something besides `\Device\<volume name>`, | 1303 | // We aren't entirely sure of the structure of the path returned by |
| 1304 | // and if we need to handle it differently | 1304 | // QueryObjectName in all contexts/environments. |
| 1305 | // (i.e. how to determine the start and end of the volume name in that case) | 1305 | // This code is written to cover the various cases that have |
| 1306 | if (!mem.eql(u16, expected_prefix, final_path[0..expected_prefix.len])) return error.Unexpected; | 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 | } |
| 1307 | | 1318 | |
| 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; |
| 1309 | const volume_name_u16 = final_path[0..file_path_begin_index]; | 1320 | 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..]; |
| 1311 | const file_name_u16 = final_path[file_path_begin_index..]; | 1322 | const file_name_u16 = final_path[file_path_begin_index..]; |
| 1312 | | 1323 | |
| 1313 | // MUP is Multiple UNC Provider, and indicates that the path is a UNC | 1324 | // MUP is Multiple UNC Provider, and indicates that the path is a UNC |