-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Windows: Deal with NT namespaced paths in GetFinalPathNameByHandle #17541
base: master
Are you sure you want to change the base?
Windows: Deal with NT namespaced paths in GetFinalPathNameByHandle #17541
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there should be Wine-specific workarounds in Zig.
Perhaps you could resolve that TODO comment there in a general way that is not Wine-specific and makes the code more correct, and also happens to solve the problem when using Wine?
Please rename the title of the PR too, to help with release notes :) (make it not sound like a wine-specific workaround) |
333e1a7
to
21837c9
Compare
21837c9
to
3aa302c
Compare
Yeah, I completely agree with this! Hopefully @squeek502's solution is that. My initial goal was to sanity check that the solution could work/was on the right path by (ab)using the PR CI checks to generate a windows zig build for me to run zig on my machine (a mac with a linux vm haha). Mainly because I don't (currently) have access to a Windows machine to build zig myself. Thank you so much @squeek502 for the solution!
I've done my best on this front! (again, can't stress enough how little I understand about the underlying problem. Just came across it and tried to hack together a workaround before a proper investigation). |
In terms of sources for this change, looking at the documention for NtQueryObject, there's nothing useful: Indeed... it doesn't even list ObjectNameInformation as one of the OBJECT_INFORMATION_CLASS values! However, looking at the wine function, it does explicitly call https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/ntdll/unix/file.c#L7062 |
3aa302c
to
a52a3ca
Compare
I've tried to edit that TODO because it wasn't really an action... as far as I can find at least there's no easy way to validate we have handled the general case. But hopefully it still keeps things clear for people looking as to where things might have gone wrong if they come across an unhandled case (as it did for me). |
a52a3ca
to
aaccbf5
Compare
90f76c8
to
d1ae96d
Compare
Thanks for taking the time to review the changes! I've implemented all the feedback (hopefully in the right way). |
d1ae96d
to
4957f7a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a good stop-gap solution if nothing else. It might be Wine-specific, but as the added comment says, we don't have a full understanding of the possible returns from NtQueryObject
with OBJECT_NAME_INFORMATION
. Additionally, because NtQueryObject
just gives us back a string (without any possible input controlling what form the path should be returned as, and no indication in the return value what form the path is in), it is possible that Windows can return a NT-prefixed (\??\
) path here as well in some situtations.
In the future, it would be good to test GetFinalPathNameByHandle/QueryObjectName on as many different filesystems/path types/file types/etc as possible to get a better understanding of what's possible in different environments.
I could whip up a test program for all the NT objects, but another solution is this program from @zodiacon's book Windows Native API Programming. I can shoot you an exe but to build it yourself:
diff --git a/Chapter04/Handles/Handles.cpp b/Chapter04/Handles/Handles.cpp
index f3a2bea..8c58f7c 100644
--- a/Chapter04/Handles/Handles.cpp
+++ b/Chapter04/Handles/Handles.cpp
@@ -38,7 +38,7 @@ NTSTATUS GetObjectName(HANDLE h, DWORD pid, std::wstring& name, bool file) {
//
HANDLE hThread;
status = NtCreateThreadEx(&hThread, THREAD_ALL_ACCESS, &procAttr, NtCurrentProcess(),
- (PTHREAD_START_ROUTINE)[](auto param) -> DWORD {
+ (PUSER_THREAD_START_ROUTINE)[](auto param) -> NTSTATUS {
auto h = (HANDLE)param;
auto status = NtQueryObject(h, ObjectNameInformation, buffer, sizeof(buffer), nullptr);
return status;
@@ -97,18 +97,15 @@ std::wstring const& GetObjectTypeName(USHORT index) {
void DisplayHandle(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX const& h) {
auto const& type = GetObjectTypeName(h.ObjectTypeIndex);
- printf("PID: %6u H: 0x%X Access: 0x%08X Att: %s Address: 0x%p Type: %ws",
- (ULONG)h.UniqueProcessId, (ULONG)h.HandleValue, h.GrantedAccess,
- HandleAttributesToString(h.HandleAttributes).c_str(),
- h.Object, type.c_str());
std::wstring name;
auto status = GetObjectName(ULongToHandle((ULONG)h.HandleValue), (ULONG)h.UniqueProcessId, name, type == L"File");
- if (NT_SUCCESS(status) && !name.empty())
- printf(" Name: %ws\n", name.c_str());
- else if (status == STATUS_ACCESS_DENIED)
- printf(" Name: <access denied>\n");
- else
- printf("\n");
+ if(!NT_SUCCESS(status) || name.empty())
+ return;
+
+ printf("PID: %6u H: 0x%X Access: 0x%08X Att: %s Address: 0x%p Type: %ws Name: %ws\n",
+ (ULONG)h.UniqueProcessId, (ULONG)h.HandleValue, h.GrantedAccess,
+ HandleAttributesToString(h.HandleAttributes).c_str(),
+ h.Object, type.c_str(), name.c_str());
}
void EnumHandles(DWORD pid, PCWSTR type) { At least on my system it seems that the returned names don't have a namespace prefix. |
@squeek502 I made made a test program to see the results of |
4957f7a
to
83732ed
Compare
When calling QueryObjectName, NT namespaced paths can be returned. This change appropriately strips the prefix to turn it into an absolute path. (The above behaviour was observed at least in Wine so far) Co-authored-by: Ryan Liptak <[email protected]>
83732ed
to
d52f9b7
Compare
This is an attempted fix for #17535, will validate that once the windows artifacts are generated for the tests for this PR and run them on my machine.