| ... | @@ -1392,16 +1392,29 @@ pub fn GetFinalPathNameByHandle( | ... | @@ -1392,16 +1392,29 @@ pub fn GetFinalPathNameByHandle( |
| 1392 | }, | 1392 | }, |
| 1393 | .Dos => { | 1393 | .Dos => { |
| 1394 | // parse the string to separate volume path from file path | 1394 | // parse the string to separate volume path from file path |
| 1395 | const expected_prefix = std.unicode.utf8ToUtf16LeStringLiteral("\\Device\\"); | 1395 | const device_prefix = std.unicode.utf8ToUtf16LeStringLiteral("\\Device\\"); |
| 1396 | | 1396 | |
| 1397 | // TODO find out if a path can start with something besides `\Device\<volume name>`, | 1397 | // We aren't entirely sure of the structure of the path returned by |
| 1398 | // and if we need to handle it differently | 1398 | // QueryObjectName in all contexts/environments. |
| 1399 | // (i.e. how to determine the start and end of the volume name in that case) | 1399 | // This code is written to cover the various cases that have |
| 1400 | if (!mem.eql(u16, expected_prefix, final_path[0..expected_prefix.len])) return error.Unexpected; | 1400 | // been encountered and solved appropriately. But note that there's |
| | 1401 | // no easy way to verify that they have all been tackled! |
| | 1402 | // (Unless you, the reader knows of one then please do action that!) |
| | 1403 | if (!mem.startsWith(u16, final_path, device_prefix)) { |
| | 1404 | // Wine seems to return NT namespaced paths starting with \??\ from QueryObjectName |
| | 1405 | // (e.g. `\??\Z:\some\path\to\a\file.txt`), in which case we can just strip the |
| | 1406 | // prefix to turn it into an absolute path. |
| | 1407 | // https://github.com/ziglang/zig/issues/26029 |
| | 1408 | // https://bugs.winehq.org/show_bug.cgi?id=39569 |
| | 1409 | return ntToWin32Namespace(final_path, out_buffer) catch |err| switch (err) { |
| | 1410 | error.NotNtPath => return error.Unexpected, |
| | 1411 | error.NameTooLong => |e| return e, |
| | 1412 | }; |
| | 1413 | } |
| 1401 | | 1414 | |
| 1402 | const file_path_begin_index = mem.indexOfPos(u16, final_path, expected_prefix.len, &[_]u16{'\\'}) orelse unreachable; | 1415 | const file_path_begin_index = mem.indexOfPos(u16, final_path, device_prefix.len, &[_]u16{'\\'}) orelse unreachable; |
| 1403 | const volume_name_u16 = final_path[0..file_path_begin_index]; | 1416 | const volume_name_u16 = final_path[0..file_path_begin_index]; |
| 1404 | const device_name_u16 = volume_name_u16[expected_prefix.len..]; | 1417 | const device_name_u16 = volume_name_u16[device_prefix.len..]; |
| 1405 | const file_name_u16 = final_path[file_path_begin_index..]; | 1418 | const file_name_u16 = final_path[file_path_begin_index..]; |
| 1406 | | 1419 | |
| 1407 | // MUP is Multiple UNC Provider, and indicates that the path is a UNC | 1420 | // MUP is Multiple UNC Provider, and indicates that the path is a UNC |