Skip to content

On a mounted VHD without a drive letter: error: unable to find zig self exe path: FileNotFound #19731

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

Closed
MarekKnapek opened this issue Apr 22, 2024 · 13 comments · Fixed by #19738
Labels
bug Observed behavior contradicts documented or intended behavior os-windows
Milestone

Comments

@MarekKnapek
Copy link

Zig Version

0.12.0

Steps to Reproduce and Observed Behavior

  • Windows x64
  • Download the latest and greatest Zig version, 0.12.0
  • Extract the zip archive to some directory
  • Create test program in the same directory Zig was extracted into [1]
  • Compile the test program: zig cc test.c

Actual Behavior:

error: unable to find zig self exe path: FileNotFound

[1]

int main(void)
{
	return 42;
}

Expected Behavior

No error message.

@MarekKnapek MarekKnapek added the bug Observed behavior contradicts documented or intended behavior label Apr 22, 2024
@squeek502
Copy link
Collaborator

Can't reproduce

C:\Users\Ryan\Programming\Zig\zig-windows-x86_64-0.12.0> zig cc test.c

C:\Users\Ryan\Programming\Zig\zig-windows-x86_64-0.12.0> a.exe

%errorlevel% 42

What filesystem are you using? Is there anything interesting about the path you're running from (non-ASCII characters, symbols, etc)?

@MarekKnapek
Copy link
Author

Yes, the problem is in path. No spaces or non-ASCII letters present in it. But I have a *.VHD hard disk image mounted. Inside the hard disk there is a single NTFS partition / volume. This partition is mounted to a (host's) NTFS directory, not to a drive letter. When I add a drive letter to the partition, everything works correctly. But I don't want to, this way I would have multitude drive letters, I prefer having multitude mount directories instead.

@squeek502
Copy link
Collaborator

If you could give some instructions on how to recreate your setup that'd be helpful.

@MarekKnapek
Copy link
Author

@MarekKnapek
Copy link
Author

ziga

@squeek502
Copy link
Collaborator

squeek502 commented Apr 22, 2024

Mostly interested in how to do this:

This partition is mounted to a (host's) NTFS directory, not to a drive letter

EDIT: Nevermind, found the option in Disk Management's New Simple Wizard Volume (Mount in the following empty NTFS folder)

@MarekKnapek
Copy link
Author

zigb

zigc

@squeek502
Copy link
Collaborator

squeek502 commented Apr 22, 2024

Can reproduce now, thanks!

C:\Users\Ryan\Programming\Zig\tmp\vhd-mount\zig-windows-x86_64-0.12.0> zig cc test.c
error: unable to find zig self exe path: FileNotFound

@squeek502 squeek502 changed the title error: unable to find zig self exe path: FileNotFound On a mounted VHD without a drive letter: error: unable to find zig self exe path: FileNotFound Apr 22, 2024
@Vexu Vexu added this to the 0.13.0 milestone Apr 22, 2024
@squeek502
Copy link
Collaborator

squeek502 commented Apr 22, 2024

The error is coming from here in GetFinalPathNameByHandle:

return error.FileNotFound;

The final path gotten from QueryObjectName is \Device\HarddiskVolume10\test.exe for me. From a cursory look, it seems like we're only looking for mount points with drive letters, so we don't end up finding anything for \Device\HarddiskVolume10.

EDIT: The mount point symlink is \??\Volume{383da0b0-717f-41b6-8c36-00500992b58d}, we only look for the \DosDevices\ prefix.

squeek502 added a commit to squeek502/zig that referenced this issue Apr 22, 2024
A volume can be mounted as a NTFS path, e.g. as C:\Mnt\Foo. In that case, IOCTL_MOUNTMGR_QUERY_POINTS gives us a mount point with a symlink value something like `\??\Volume{383da0b0-717f-41b6-8c36-00500992b58d}`. In order to get the `C:\Mnt\Foo` path, we can query the mountmgr again using IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH.

Fixes ziglang#19731
@MarekKnapek
Copy link
Author

Quick and dirty program written in C. seems to work correctly. Should be easy to port from C to Zig.

#include <assert.h> /* assert */
#include <stdio.h> /* wprintf */

#include <windows.h>


#define count(x) (sizeof(x) / sizeof((x)[0]))


int wmain(int argc, wchar_t** argv)
{
	if(argc != 2)
	{
		return __LINE__;
	}
	HANDLE file = CreateFileW(argv[1], FILE_GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL);
	if(file == INVALID_HANDLE_VALUE)
	{
		return __LINE__;
	}
	wchar_t path[1 * 1024]; /* max len is 64kB, thus 32k wchars */
	DWORD dw = GetFinalPathNameByHandleW(file, path, count(path), FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
	assert(dw != count(path));
	if(dw == 0 || dw > count(path))
	{
		return __LINE__;
	}
	wchar_t const* name;
	size_t len;
	if
	(
		dw >= 7 &&
		path[0] == L'\\' &&
		path[1] == L'\\' &&
		path[2] == L'?' &&
		path[3] == L'\\' &&
		((path[4] >= L'a' && path[4] <= L'z') || (path[4] >= L'A' && path[4] <= L'Z')) &&
		path[5] == L':' &&
		path[6] == L'\\'
	)
	{
		name = path + 4;
		len = dw - 4;
	}
	else
	{
		name = path;
		len = dw;
	}
	wprintf(L"Final Win32 name is: %s\n", name);
}

@squeek502
Copy link
Collaborator

Zig prefers NtDll implementations, see #1840.

I have a PR that should fix this problem, though: #19738

@MarekKnapek
Copy link
Author

Thank you for speedy response. That is great. But wow, depending on NTAPI in general purpose tool (programming language) is ... bold.

squeek502 added a commit to squeek502/zig that referenced this issue Apr 22, 2024
A volume can be mounted as a NTFS path, e.g. as C:\Mnt\Foo. In that case, IOCTL_MOUNTMGR_QUERY_POINTS gives us a mount point with a symlink value something like `\??\Volume{383da0b0-717f-41b6-8c36-00500992b58d}`. In order to get the `C:\Mnt\Foo` path, we can query the mountmgr again using IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH.

Fixes ziglang#19731
squeek502 added a commit to squeek502/zig that referenced this issue Apr 23, 2024
A volume can be mounted as a NTFS path, e.g. as C:\Mnt\Foo. In that case, IOCTL_MOUNTMGR_QUERY_POINTS gives us a mount point with a symlink value something like `\??\Volume{383da0b0-717f-41b6-8c36-00500992b58d}`. In order to get the `C:\Mnt\Foo` path, we can query the mountmgr again using IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH.

Fixes ziglang#19731
squeek502 added a commit to squeek502/zig that referenced this issue Apr 23, 2024
A volume can be mounted as a NTFS path, e.g. as C:\Mnt\Foo. In that case, IOCTL_MOUNTMGR_QUERY_POINTS gives us a mount point with a symlink value something like `\??\Volume{383da0b0-717f-41b6-8c36-00500992b58d}`. In order to get the `C:\Mnt\Foo` path, we can query the mountmgr again using IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH.

Fixes ziglang#19731
andrewrk pushed a commit that referenced this issue Apr 24, 2024
A volume can be mounted as a NTFS path, e.g. as C:\Mnt\Foo. In that case, IOCTL_MOUNTMGR_QUERY_POINTS gives us a mount point with a symlink value something like `\??\Volume{383da0b0-717f-41b6-8c36-00500992b58d}`. In order to get the `C:\Mnt\Foo` path, we can query the mountmgr again using IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH.

Fixes #19731
@andrewrk
Copy link
Member

Fix cherry-picked into 0.12.x branch as e36bf2b.

@andrewrk andrewrk modified the milestones: 0.14.0, 0.13.0 May 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior os-windows
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants