Skip to content

Commit fbd7ea1

Browse files
committed
✨ Add support for explicit API layers
fixes #29 refs #28
1 parent bbc8d3b commit fbd7ea1

File tree

7 files changed

+78
-9
lines changed

7 files changed

+78
-9
lines changed

src/APILayer.hpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,14 @@ struct APILayer {
2323
enum class Value {
2424
Enabled,
2525
Disabled,
26+
NotInstalled,
2627
Win32_NotDWORD,
2728
};
29+
enum class Kind {
30+
Explicit,
31+
Implicit,
32+
};
2833

29-
APILayer() = delete;
3034
APILayer(
3135
const APILayerStore* source,
3236
const std::filesystem::path& manifestPath,
@@ -35,15 +39,31 @@ struct APILayer {
3539
mManifestPath(manifestPath),
3640
mValue(value) {}
3741

42+
static APILayer MakeAbsentExplicit(const std::string_view name) {
43+
APILayer ret {nullptr, {}, Value::NotInstalled};
44+
ret.mReferencedName = name;
45+
return ret;
46+
}
47+
48+
Kind GetKind() const noexcept;
49+
3850
const APILayerStore* mSource {nullptr};
3951
std::filesystem::path mManifestPath;
4052
Value mValue;
4153

54+
/// Only set for explicit API layers that are referenced but not
55+
/// present
56+
std::string mReferencedName;
57+
58+
[[nodiscard]]
4259
constexpr bool IsEnabled() const noexcept {
4360
return mValue == Value::Enabled;
4461
};
4562

4663
bool operator==(const APILayer&) const noexcept = default;
64+
65+
private:
66+
APILayer() = default;
4767
};
4868

4969
struct Extension {

src/APILayerDetails.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <fstream>
88

99
#include "APILayer.hpp"
10+
#include "APILayerStore.hpp"
1011
#include "Platform.hpp"
1112

1213
namespace FredEmmott::OpenXRLayers {
@@ -31,6 +32,16 @@ static void SetStringOrNumber(
3132
}
3233
}
3334

35+
APILayer::Kind APILayer::GetKind() const noexcept {
36+
if (!mSource) {
37+
/// If we didn't find it in the registry or manifest locations,
38+
/// it can't be implicit.
39+
return Kind::Explicit;
40+
}
41+
42+
return mSource->GetKind();
43+
}
44+
3445
APILayerDetails::APILayerDetails(const std::filesystem::path& jsonPath) {
3546
if (!std::filesystem::exists(jsonPath)) {
3647
mState = State::NoJsonFile;

src/APILayerStore.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ class APILayerStore {
1313
public:
1414
virtual ~APILayerStore() = default;
1515

16+
virtual APILayer::Kind GetKind() const noexcept = 0;
17+
1618
// e.g. "Win64-HKLM"
1719
virtual std::string GetDisplayName() const noexcept = 0;
1820
virtual std::vector<APILayer> GetAPILayers() const noexcept = 0;

src/linters/DisabledByEnvironmentLinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ class DisabledByEnvironmentLinter final : public Linter {
1717
continue;
1818
}
1919

20+
if (layer.GetKind() != APILayer::Kind::Implicit) {
21+
continue;
22+
}
23+
2024
const auto& enableEnv = details.mEnableEnvironment;
2125
if ((!enableEnv.empty()) && !std::getenv(enableEnv.c_str())) {
2226
errors.push_back(

src/linters/SkippedByLoaderLinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ class SkippedByLoaderLinter final : public Linter {
3232
continue;
3333
}
3434

35+
if (layer.GetKind() != APILayer::Kind::Implicit) {
36+
continue;
37+
}
38+
3539
if (!layer.mSource->IsForCurrentArchitecture()) {
3640
continue;
3741
}

src/windows/WindowsAPILayerStore.cpp

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,19 @@
2020

2121
namespace FredEmmott::OpenXRLayers {
2222

23-
static constexpr auto SubKey {
23+
static constexpr auto ImplicitSubKey {
2424
L"SOFTWARE\\Khronos\\OpenXR\\1\\ApiLayers\\Implicit"};
25+
static constexpr auto ExplicitSubKey {
26+
L"SOFTWARE\\Khronos\\OpenXR\\1\\ApiLayers\\Explicit"};
2527

2628
WindowsAPILayerStore::WindowsAPILayerStore(
2729
std::string_view displayName,
30+
APILayer::Kind kind,
2831
RegistryBitness bitness,
2932
HKEY rootKey,
3033
REGSAM desiredAccess)
3134
: mDisplayName(displayName),
35+
mLayerKind(kind),
3236
mRegistryBitness(bitness),
3337
mRootKey(rootKey) {
3438
REGSAM samFlags {desiredAccess};
@@ -43,7 +47,7 @@ WindowsAPILayerStore::WindowsAPILayerStore(
4347
if (
4448
RegCreateKeyExW(
4549
rootKey,
46-
SubKey,
50+
(kind == APILayer::Kind::Implicit) ? ImplicitSubKey : ExplicitSubKey,
4751
0,
4852
nullptr,
4953
REG_OPTION_NON_VOLATILE,
@@ -59,11 +63,15 @@ WindowsAPILayerStore::WindowsAPILayerStore(
5963
return;
6064
}
6165
mEvent.reset(CreateEvent(nullptr, false, false, nullptr));
62-
this->Poll();
66+
this->WindowsAPILayerStore::Poll();
6367
}
6468

6569
WindowsAPILayerStore::~WindowsAPILayerStore() = default;
6670

71+
APILayer::Kind WindowsAPILayerStore::GetKind() const noexcept {
72+
return mLayerKind;
73+
}
74+
6775
std::string WindowsAPILayerStore::GetDisplayName() const noexcept {
6876
return mDisplayName;
6977
}
@@ -139,20 +147,23 @@ class ReadOnlyWindowsAPILayerStore final : public WindowsAPILayerStore {
139147
public:
140148
ReadOnlyWindowsAPILayerStore(
141149
std::string_view displayName,
150+
APILayer::Kind kind,
142151
RegistryBitness bitness,
143152
HKEY rootKey)
144-
: WindowsAPILayerStore(displayName, bitness, rootKey, KEY_READ) {}
153+
: WindowsAPILayerStore(displayName, kind, bitness, rootKey, KEY_READ) {}
145154
};
146155

147156
class ReadWriteWindowsAPILayerStore final : public WindowsAPILayerStore,
148157
public ReadWriteAPILayerStore {
149158
public:
150159
ReadWriteWindowsAPILayerStore(
151160
std::string_view displayName,
161+
APILayer::Kind kind,
152162
RegistryBitness bitness,
153163
HKEY rootKey)
154164
: WindowsAPILayerStore(
155165
displayName,
166+
kind,
156167
bitness,
157168
rootKey,
158169
KEY_READ | KEY_WRITE) {}
@@ -220,19 +231,32 @@ class ReadWriteWindowsAPILayerStore final : public WindowsAPILayerStore,
220231
template <class TInterface, class TConcrete>
221232
std::span<const TInterface*> GetStaticStores() noexcept {
222233
using RB = WindowsAPILayerStore::RegistryBitness;
234+
using enum APILayer::Kind;
223235
static const TConcrete sHKLM64 {
224-
"Win64-HKLM", RB::Wow64_64, HKEY_LOCAL_MACHINE};
236+
"Win64-HKLM", Implicit, RB::Wow64_64, HKEY_LOCAL_MACHINE};
225237
static const TConcrete sHKCU64 {
226-
"Win64-HKCU", RB::Wow64_64, HKEY_CURRENT_USER};
238+
"Win64-HKCU", Implicit, RB::Wow64_64, HKEY_CURRENT_USER};
227239
static const TConcrete sHKLM32 {
228-
"Win32-HKLM", RB::Wow64_32, HKEY_LOCAL_MACHINE};
240+
"Win32-HKLM", Implicit, RB::Wow64_32, HKEY_LOCAL_MACHINE};
229241
static const TConcrete sHKCU32 {
230-
"Win32-HKCU", RB::Wow64_32, HKEY_CURRENT_USER};
242+
"Win32-HKCU", Implicit, RB::Wow64_32, HKEY_CURRENT_USER};
243+
static const TConcrete sExplicitHKLM64 {
244+
"Explicit Win64-HKLM", Explicit, RB::Wow64_64, HKEY_LOCAL_MACHINE};
245+
static const TConcrete sExplicitHKCU64 {
246+
"Explicit Win64-HKCU", Explicit, RB::Wow64_64, HKEY_CURRENT_USER};
247+
static const TConcrete sExplicitHKLM32 {
248+
"Explicit Win32-HKLM", Explicit, RB::Wow64_32, HKEY_LOCAL_MACHINE};
249+
static const TConcrete sExplicitHKCU32 {
250+
"Explicit Win32-HKCU", Explicit, RB::Wow64_32, HKEY_CURRENT_USER};
231251
static const TInterface* sStores[] {
232252
&sHKLM64,
233253
&sHKCU64,
234254
&sHKLM32,
235255
&sHKCU32,
256+
&sExplicitHKLM64,
257+
&sExplicitHKCU64,
258+
&sExplicitHKLM32,
259+
&sExplicitHKCU32,
236260
};
237261
return sStores;
238262
}

src/windows/WindowsAPILayerStore.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ class WindowsAPILayerStore : public virtual APILayerStore {
2121
WindowsAPILayerStore() = delete;
2222
~WindowsAPILayerStore() override;
2323

24+
APILayer::Kind GetKind() const noexcept override;
25+
2426
std::string GetDisplayName() const noexcept override;
2527

2628
std::vector<APILayer> GetAPILayers() const noexcept override;
@@ -42,6 +44,7 @@ class WindowsAPILayerStore : public virtual APILayerStore {
4244
protected:
4345
WindowsAPILayerStore(
4446
std::string_view displayName,
47+
APILayer::Kind layerKind,
4548
RegistryBitness bitness,
4649
HKEY rootKey,
4750
REGSAM desiredAccess);
@@ -51,6 +54,7 @@ class WindowsAPILayerStore : public virtual APILayerStore {
5154

5255
private:
5356
const std::string mDisplayName;
57+
const APILayer::Kind mLayerKind;
5458
const RegistryBitness mRegistryBitness;
5559
const HKEY mRootKey;
5660
};

0 commit comments

Comments
 (0)