Files
Billy Laws 1ac3d3c5a6 Windows: Extend user handle access masks in callbacks where necessary
While most applications will just create ALL_ACCESS handles which
support the additional operations FEX needs over the regular windows syscall
(usually just QUERY_INFORMATION to lookup the thread object), it is
valid for them to pass in the minimal set required for each operation
and windows/wine will reject any other operations (e.g. querying the TEB
base on a handle with only the SUSPEND right). Windows permits
duplicating handles to extend their permissions given the process itself
has such permissions, so do that as necessary for the operations FEX
needs.
2025-08-12 03:19:20 +01:00

50 lines
1.1 KiB
C++

// SPDX-License-Identifier: MIT
#pragma once
#include <winternl.h>
namespace FEX::Windows {
class ScopedHandle final {
public:
explicit ScopedHandle(HANDLE Handle)
: Handle(Handle) {}
// Move-only type
ScopedHandle(const ScopedHandle&) = delete;
ScopedHandle& operator=(ScopedHandle&) = delete;
ScopedHandle(ScopedHandle&& rhs)
: Handle(rhs.Handle) {
rhs.Handle = INVALID_HANDLE_VALUE;
}
~ScopedHandle() {
if (Handle != INVALID_HANDLE_VALUE) {
NtClose(Handle);
}
}
HANDLE operator*() const {
return Handle;
}
private:
HANDLE Handle;
};
bool ValidateHandleAccess(HANDLE Handle, ACCESS_MASK Access) {
OBJECT_BASIC_INFORMATION Info;
if (NtQueryObject(Handle, ObjectBasicInformation, &Info, sizeof(Info), nullptr)) {
return false;
}
return (Info.GrantedAccess & Access) == Access;
}
ScopedHandle DupHandle(HANDLE Handle, ACCESS_MASK Access) {
HANDLE Duplicated = INVALID_HANDLE_VALUE;
NtDuplicateObject(NtCurrentProcess(), Handle, NtCurrentProcess(), &Duplicated, Access, 0, 0);
return ScopedHandle {Duplicated};
}
} // namespace FEX::Windows