-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
std.fs.selfExePath converts drive letter to *:/ on secondary drive on windows #23276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Yes, this is done to follow symlinks: #16885 My guess is that this is something going wrong in diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig
index 54a98c174f..46b76beae1 100644
--- a/lib/std/os/windows.zig
+++ b/lib/std/os/windows.zig
@@ -1286,6 +1286,8 @@ pub fn GetFinalPathNameByHandle(
else => |e| return e,
};
+ std.debug.print("final_path: {}\n", .{std.unicode.fmtUtf16Le(final_path)});
+
switch (fmt.volume_name) {
.Nt => {
// the returned path is already in .Nt format
@@ -1367,6 +1369,8 @@ pub fn GetFinalPathNameByHandle(
@ptrCast(@alignCast(&output_buf[mount_point.SymbolicLinkNameOffset])),
)[0 .. mount_point.SymbolicLinkNameLength / 2];
+ std.debug.print("mount point symlink: {}\n", .{std.unicode.fmtUtf16Le(symlink)});
+
// Look for `\DosDevices\` prefix. We don't really care if there are more than one symlinks
// with traditional DOS drive letters, so pick the first one available.
var prefix_buf = std.unicode.utf8ToUtf16LeStringLiteral("\\DosDevices\\"); Here's the output when I run the test program with those changes:
(feel free to redact any part of the path you don't want to share) |
This is the result I get after editing the
When running on |
I get
In Powershell you can query the list of mount points with
|
This comment may end up being relevant (i.e. choosing the first entry may not always be a good idea): Lines 1370 to 1371 in 074dd4d
Will try to find some info on EDIT: Unable to find any info about |
I ran Get-PSDrive but found no * entry. I did, however, insert a couple of usb-drives and they all seemed to work. It may be something to do with my secondary drive. I tried to change the drive letter but that didn't help. |
I think I have narrowed down where the error comes from, the function Input: Didn't include everything, only focused on diff, there are some more bytes before and I think after as well. It seems EDIT: same problem with |
Finally found it, it seems to fetch the data from regedit under HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices, for some reason I had the same drive connected to two keys: \DosDevices\*: and \DosDevices\D: Since this had nothing to do with zig but my configuration on my computer I will close this issue. EDIT: @squeek502 this was connected to what you mentioned with selecting the first entry, do not know in what circumstance more than one appears, but I seem to have gotten it at one point. |
Thanks for all the info. Worth noting that Zig is trying to emulate GetFinalPathNameByHandleW (see #1840), so when I get a chance I'll try reproducing the problem and then check what GetFinalPathNameByHandleW returns and go from there. |
@squeek502 Fwiw GetFinalPathNameByHandleW does the mapping via IOCTLs to the MountMgr device. VOLUME_NAME_DOS -> IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH (maybe could use RtlVolumeDeviceToDosName?) |
@relapids the current implementation is doing exactly that: Lines 1317 to 1446 in 0312391
|
Zig Version
0.14.0-dev.1472+3929cac15
Steps to Reproduce and Observed Behavior
I am trying to get the
std.fs.Dir
to the self executable so that files relative to the executable can be loaded. Thestd.fs.cwd()
cannot be used in this case since the executable can be run from any directory. I get a problem in windows when using multiple drives, it seems to only work for the main driveC:/
but the path to my other driveD:/
is converted to*:/
when usingstd.fs.selfExePath
.To reproduce:
When located on
C:/
it produces:ExePath: C:/...
When located on
D:/
it produces:ExePath: *:/...
What I have gathered from other issues/proposals is that the problem lies in
std.fs.Dir.realpath
, this function is proposed to be removed in #19353 since it is buggy, but since the proposal is about removing realpath and not to fix it I created this issue.I have circumvented this bug by not calling the selfExePath but instead use
std.os.windows.peb().ProcessParameters.ImagePathName
directly for windows builds and convert it to utf8 without using realpath in between, but I do not know if this approach is reliable.What I can see from
std.fs.openSelfExe
it does not use realpath, is it really necessary to use realpath in selfExePath?Is there another way that I haven't listed to get the absolute path or
std.fs.Dir
to the executable that is reliable?Expected Behavior
When located on D:/ it should produce:
ExePath: D:/...
The text was updated successfully, but these errors were encountered: