mirror of
https://github.com/VSCodium/policy-watcher.git
synced 2025-12-09 19:43:17 -06:00
Merge remote-tracking branch 'upstream/main'
This commit is contained in:
commit
60643232ab
14
.vscode/c_cpp_properties.json
vendored
14
.vscode/c_cpp_properties.json
vendored
@ -13,7 +13,21 @@
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++17",
|
||||
"intelliSenseMode": "windows-msvc-x64"
|
||||
},
|
||||
{
|
||||
"name": "Mac",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"${workspaceFolder}/node_modules/node-addon-api",
|
||||
"${default}"
|
||||
],
|
||||
"defines": ["_DEBUG", "MACOS"],
|
||||
"compilerPath": "/usr/bin/clang++",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++17",
|
||||
"intelliSenseMode": "macos-clang-x64"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
|
||||
12
.vscode/launch.json
vendored
Normal file
12
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Launch Program",
|
||||
"program": "${workspaceFolder}/index.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
16
.vscode/settings.json
vendored
16
.vscode/settings.json
vendored
@ -67,6 +67,18 @@
|
||||
"xstring": "cpp",
|
||||
"xtr1common": "cpp",
|
||||
"xtree": "cpp",
|
||||
"xutility": "cpp"
|
||||
}
|
||||
"xutility": "cpp",
|
||||
"__bit_reference": "cpp",
|
||||
"__locale": "cpp",
|
||||
"__split_buffer": "cpp",
|
||||
"__threading_support": "cpp",
|
||||
"__verbose_abort": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"execution": "cpp",
|
||||
"string_view": "cpp",
|
||||
"variant": "cpp",
|
||||
"bitset": "cpp",
|
||||
"print": "cpp"
|
||||
},
|
||||
}
|
||||
|
||||
@ -16,6 +16,9 @@
|
||||
['OS=="mac"', {
|
||||
"sources": [
|
||||
"src/macos/PolicyWatcher.cc",
|
||||
"src/macos/StringPolicy.cc",
|
||||
"src/macos/NumberPolicy.cc",
|
||||
"src/macos/BooleanPolicy.cc"
|
||||
],
|
||||
"defines": [
|
||||
"MACOS",
|
||||
@ -38,7 +41,8 @@
|
||||
"sources": [
|
||||
"src/windows/PolicyWatcher.cc",
|
||||
"src/windows/StringPolicy.cc",
|
||||
"src/windows/NumberPolicy.cc"
|
||||
"src/windows/NumberPolicy.cc",
|
||||
"src/windows/BooleanPolicy.cc"
|
||||
],
|
||||
"defines": [
|
||||
"WINDOWS"
|
||||
|
||||
7
index.d.ts
vendored
7
index.d.ts
vendored
@ -9,9 +9,10 @@ interface Watcher {
|
||||
|
||||
type StringPolicy = { type: "string" };
|
||||
type NumberPolicy = { type: "number" };
|
||||
type BooleanPolicy = { type: "boolean" };
|
||||
|
||||
export interface Policies {
|
||||
[policyName: string]: StringPolicy | NumberPolicy;
|
||||
[policyName: string]: StringPolicy | NumberPolicy | BooleanPolicy;
|
||||
}
|
||||
|
||||
export type PolicyUpdate<T extends Policies> = {
|
||||
@ -19,9 +20,11 @@ export type PolicyUpdate<T extends Policies> = {
|
||||
| undefined
|
||||
| (T[K] extends StringPolicy
|
||||
? string
|
||||
: (T[K] extends BooleanPolicy
|
||||
? boolean
|
||||
: T[K] extends NumberPolicy
|
||||
? number
|
||||
: never);
|
||||
: never));
|
||||
};
|
||||
|
||||
export function createWatcher<T extends Policies>(
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@vscodium/policy-watcher",
|
||||
"version": "1.1.8",
|
||||
"version": "1.3.0-2503241459",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@vscodium/policy-watcher",
|
||||
"version": "1.1.8",
|
||||
"version": "1.3.0-2503241459",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bindings": "^1.5.0",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vscodium/policy-watcher",
|
||||
"version": "1.1.10-2503041159",
|
||||
"version": "1.3.0-2503241459",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
|
||||
@ -10,11 +10,18 @@
|
||||
|
||||
using namespace Napi;
|
||||
|
||||
enum class PolicyRefreshResult {
|
||||
Updated,
|
||||
Unchanged,
|
||||
Removed,
|
||||
NotSet
|
||||
};
|
||||
|
||||
class Policy
|
||||
{
|
||||
public:
|
||||
virtual ~Policy() {}
|
||||
virtual bool refresh() = 0;
|
||||
virtual PolicyRefreshResult refresh() = 0;
|
||||
virtual Value getValue(Env env) const = 0;
|
||||
const std::string name;
|
||||
|
||||
|
||||
@ -14,6 +14,11 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef MACOS
|
||||
#define Boolean CFBoolean
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#endif
|
||||
|
||||
using namespace Napi;
|
||||
|
||||
class PolicyWatcher : public AsyncProgressQueueWorker<const Policy *>
|
||||
@ -24,6 +29,7 @@ public:
|
||||
|
||||
void AddStringPolicy(const std::string name);
|
||||
void AddNumberPolicy(const std::string name);
|
||||
void AddBooleanPolicy(const std::string name);
|
||||
|
||||
void OnExecute(Napi::Env env);
|
||||
void Execute(const ExecutionProgress &progress);
|
||||
@ -38,6 +44,13 @@ protected:
|
||||
#ifdef WINDOWS
|
||||
HANDLE handles[4];
|
||||
#endif
|
||||
|
||||
#ifdef MACOS
|
||||
FSEventStreamRef stream;
|
||||
dispatch_semaphore_t sem;
|
||||
bool disposed;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -20,6 +20,7 @@ PolicyWatcher::~PolicyWatcher()
|
||||
|
||||
void PolicyWatcher::AddStringPolicy(const std::string name) {}
|
||||
void PolicyWatcher::AddNumberPolicy(const std::string name) {}
|
||||
void PolicyWatcher::AddBooleanPolicy(const std::string name) {}
|
||||
void PolicyWatcher::OnExecute(Napi::Env env) {}
|
||||
void PolicyWatcher::Execute(const ExecutionProgress &progress) {}
|
||||
void PolicyWatcher::OnProgress(const Policy *const *policies, size_t count) {}
|
||||
|
||||
36
src/macos/BooleanPolicy.cc
Normal file
36
src/macos/BooleanPolicy.cc
Normal file
@ -0,0 +1,36 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
#include "BooleanPolicy.hh"
|
||||
|
||||
using namespace Napi;
|
||||
|
||||
BooleanPolicy::BooleanPolicy(const std::string name, const std::string &productName)
|
||||
: PreferencesPolicy(name, productName)
|
||||
{
|
||||
}
|
||||
|
||||
Value BooleanPolicy::getJSValue(Env env, bool value) const
|
||||
{
|
||||
return Napi::Boolean::New(env, value);
|
||||
}
|
||||
|
||||
std::optional<bool> BooleanPolicy::read() const
|
||||
{
|
||||
auto pref = CFPreferencesCopyAppValue(key, appID);
|
||||
|
||||
if (pref == NULL)
|
||||
return std::nullopt;
|
||||
|
||||
if (CFGetTypeID(pref) != CFBooleanGetTypeID())
|
||||
{
|
||||
CFRelease(pref);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool value = (pref == kCFBooleanTrue);
|
||||
CFRelease(pref);
|
||||
return value;
|
||||
}
|
||||
24
src/macos/BooleanPolicy.hh
Normal file
24
src/macos/BooleanPolicy.hh
Normal file
@ -0,0 +1,24 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef MAC_BOOLEAN_POLICY_H
|
||||
#define MAC_BOOLEAN_POLICY_H
|
||||
|
||||
#include <napi.h>
|
||||
#include "PreferencesPolicy.hh"
|
||||
|
||||
using namespace Napi;
|
||||
|
||||
class BooleanPolicy : public PreferencesPolicy<bool>
|
||||
{
|
||||
public:
|
||||
BooleanPolicy(const std::string name, const std::string &productName);
|
||||
std::optional<bool> read() const override;
|
||||
|
||||
protected:
|
||||
Value getJSValue(Env env, bool value) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
42
src/macos/NumberPolicy.cc
Normal file
42
src/macos/NumberPolicy.cc
Normal file
@ -0,0 +1,42 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
#include "NumberPolicy.hh"
|
||||
|
||||
using namespace Napi;
|
||||
|
||||
NumberPolicy::NumberPolicy(const std::string name, const std::string &productName)
|
||||
: PreferencesPolicy(name, productName)
|
||||
{
|
||||
}
|
||||
|
||||
Value NumberPolicy::getJSValue(Env env, long long value) const
|
||||
{
|
||||
return Number::New(env, static_cast<double>(value));
|
||||
}
|
||||
|
||||
std::optional<long long> NumberPolicy::read() const
|
||||
{
|
||||
auto pref = CFPreferencesCopyAppValue(key, appID);
|
||||
|
||||
if (pref == NULL)
|
||||
return std::nullopt;
|
||||
|
||||
if (CFGetTypeID(pref) != CFNumberGetTypeID())
|
||||
{
|
||||
CFRelease(pref);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
long long value;
|
||||
if (CFNumberGetValue((CFNumberRef)pref, kCFNumberLongLongType, &value))
|
||||
{
|
||||
CFRelease(pref);
|
||||
return value;
|
||||
}
|
||||
|
||||
CFRelease(pref);
|
||||
return std::nullopt;
|
||||
}
|
||||
24
src/macos/NumberPolicy.hh
Normal file
24
src/macos/NumberPolicy.hh
Normal file
@ -0,0 +1,24 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef MAC_NUMBER_POLICY_H
|
||||
#define MAC_NUMBER_POLICY_H
|
||||
|
||||
#include <napi.h>
|
||||
#include "PreferencesPolicy.hh"
|
||||
|
||||
using namespace Napi;
|
||||
|
||||
class NumberPolicy : public PreferencesPolicy<long long>
|
||||
{
|
||||
public:
|
||||
NumberPolicy(const std::string name, const std::string &productName);
|
||||
std::optional<long long> read() const override;
|
||||
|
||||
protected:
|
||||
Value getJSValue(Env env, long long value) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -4,23 +4,136 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
#include "../PolicyWatcher.hh"
|
||||
#include "StringPolicy.hh"
|
||||
#include "NumberPolicy.hh"
|
||||
#include "BooleanPolicy.hh"
|
||||
#include <thread>
|
||||
|
||||
using namespace Napi;
|
||||
|
||||
static void fsevents_callback(ConstFSEventStreamRef streamRef,
|
||||
void *clientCallBackInfo,
|
||||
size_t numEvents,
|
||||
void *eventPaths,
|
||||
const FSEventStreamEventFlags eventFlags[],
|
||||
const FSEventStreamEventId eventIds[])
|
||||
{
|
||||
dispatch_semaphore_t *sem = (dispatch_semaphore_t *)clientCallBackInfo;
|
||||
dispatch_semaphore_signal(*sem);
|
||||
}
|
||||
|
||||
PolicyWatcher::PolicyWatcher(std::string vendorName, std::string productName, const Function &okCallback)
|
||||
: AsyncProgressQueueWorker(okCallback),
|
||||
vendorName(vendorName),
|
||||
productName(productName)
|
||||
productName(productName),
|
||||
stream(nullptr),
|
||||
sem(nullptr),
|
||||
disposed(false)
|
||||
{
|
||||
}
|
||||
|
||||
PolicyWatcher::~PolicyWatcher()
|
||||
{
|
||||
if (stream) {
|
||||
FSEventStreamStop(stream);
|
||||
FSEventStreamInvalidate(stream);
|
||||
FSEventStreamRelease(stream);
|
||||
}
|
||||
if (sem) {
|
||||
dispatch_release(sem);
|
||||
}
|
||||
}
|
||||
|
||||
void PolicyWatcher::AddStringPolicy(const std::string name) {}
|
||||
void PolicyWatcher::AddNumberPolicy(const std::string name) {}
|
||||
void PolicyWatcher::OnExecute(Napi::Env env) {}
|
||||
void PolicyWatcher::Execute(const ExecutionProgress &progress) {}
|
||||
void PolicyWatcher::OnProgress(const Policy *const *policies, size_t count) {}
|
||||
void PolicyWatcher::Dispose() {}
|
||||
void PolicyWatcher::AddStringPolicy(const std::string name)
|
||||
{
|
||||
policies.push_back(std::make_unique<StringPolicy>(name, productName));
|
||||
}
|
||||
void PolicyWatcher::AddNumberPolicy(const std::string name)
|
||||
{
|
||||
policies.push_back(std::make_unique<NumberPolicy>(name, productName));
|
||||
}
|
||||
|
||||
void PolicyWatcher::AddBooleanPolicy(const std::string name)
|
||||
{
|
||||
policies.push_back(std::make_unique<BooleanPolicy>(name, productName));
|
||||
}
|
||||
|
||||
void PolicyWatcher::OnExecute(Napi::Env env)
|
||||
{
|
||||
AsyncProgressQueueWorker::OnExecute(env);
|
||||
}
|
||||
|
||||
void PolicyWatcher::Execute(const ExecutionProgress &progress)
|
||||
{
|
||||
std::vector<const Policy *> updatedPolicies;
|
||||
bool first = true;
|
||||
|
||||
// Watch for changes
|
||||
CFStringRef path = CFSTR("/Library/Managed Preferences/");
|
||||
sem = dispatch_semaphore_create(0);
|
||||
FSEventStreamContext context = {0, &sem, NULL, NULL, NULL};
|
||||
stream = FSEventStreamCreate(NULL,
|
||||
&fsevents_callback,
|
||||
&context,
|
||||
CFArrayCreate(NULL, (const void **)&path, 1, NULL),
|
||||
kFSEventStreamEventIdSinceNow,
|
||||
1.0,
|
||||
kCFStreamEventNone);
|
||||
|
||||
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
|
||||
FSEventStreamSetDispatchQueue(stream, queue);
|
||||
FSEventStreamStart(stream);
|
||||
|
||||
while (!disposed)
|
||||
{
|
||||
updatedPolicies.clear();
|
||||
bool update = false;
|
||||
for (auto &policy : policies)
|
||||
{
|
||||
switch(policy->refresh())
|
||||
{
|
||||
case PolicyRefreshResult::Updated:
|
||||
updatedPolicies.push_back(policy.get());
|
||||
update = true;
|
||||
break;
|
||||
case PolicyRefreshResult::Unchanged:
|
||||
updatedPolicies.push_back(policy.get());
|
||||
break;
|
||||
case PolicyRefreshResult::Removed:
|
||||
update = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (first || update)
|
||||
progress.Send(&updatedPolicies[0], updatedPolicies.size());
|
||||
|
||||
first = false;
|
||||
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
|
||||
}
|
||||
}
|
||||
|
||||
void PolicyWatcher::OnProgress(const Policy *const *policies, size_t count)
|
||||
{
|
||||
HandleScope scope(Env());
|
||||
auto result = Object::New(Env());
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
Callback().Call(Receiver().Value(), {result});
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < count; i++)
|
||||
result.Set(policies[i]->name, policies[i]->getValue(Env()));
|
||||
|
||||
Callback().Call(Receiver().Value(), {result});
|
||||
}
|
||||
|
||||
void PolicyWatcher::Dispose()
|
||||
{
|
||||
disposed = true;
|
||||
if (sem) {
|
||||
dispatch_semaphore_signal(sem);
|
||||
}
|
||||
}
|
||||
|
||||
72
src/macos/PreferencesPolicy.hh
Normal file
72
src/macos/PreferencesPolicy.hh
Normal file
@ -0,0 +1,72 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef PREFERENCES_POLICY_H
|
||||
#define PREFERENCES_POLICY_H
|
||||
|
||||
#include <napi.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include "../Policy.hh"
|
||||
|
||||
using namespace Napi;
|
||||
|
||||
template <typename T>
|
||||
class PreferencesPolicy : public Policy
|
||||
{
|
||||
public:
|
||||
PreferencesPolicy(const std::string name, const std::string &productName)
|
||||
: Policy(name),
|
||||
appID(CFStringCreateWithCString(NULL, productName.c_str(), kCFStringEncodingUTF8)),
|
||||
key(CFStringCreateWithCString(NULL, name.c_str(), kCFStringEncodingUTF8))
|
||||
{
|
||||
}
|
||||
|
||||
~PreferencesPolicy()
|
||||
{
|
||||
CFRelease(appID);
|
||||
CFRelease(key);
|
||||
}
|
||||
|
||||
PolicyRefreshResult refresh()
|
||||
{
|
||||
auto newValue = read();
|
||||
|
||||
// Check for no value or removal
|
||||
if (!newValue.has_value())
|
||||
{
|
||||
if (!value.has_value())
|
||||
return PolicyRefreshResult::NotSet;
|
||||
|
||||
value.reset();
|
||||
return PolicyRefreshResult::Removed;
|
||||
}
|
||||
|
||||
// Is the value updated?
|
||||
if (value != newValue)
|
||||
{
|
||||
value = newValue;
|
||||
return PolicyRefreshResult::Updated;
|
||||
}
|
||||
|
||||
return PolicyRefreshResult::Unchanged;
|
||||
}
|
||||
|
||||
Value getValue(Env env) const
|
||||
{
|
||||
if (!value.has_value())
|
||||
return env.Undefined();
|
||||
return getJSValue(env, *value); // value.value() is only supported after macOS 10.13
|
||||
}
|
||||
|
||||
protected:
|
||||
std::optional<T> value;
|
||||
const CFStringRef appID;
|
||||
const CFStringRef key;
|
||||
virtual Value getJSValue(Env env, T value) const = 0;
|
||||
virtual std::optional<T> read() const = 0;
|
||||
|
||||
private:
|
||||
};
|
||||
#endif
|
||||
46
src/macos/StringPolicy.cc
Normal file
46
src/macos/StringPolicy.cc
Normal file
@ -0,0 +1,46 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
#include "StringPolicy.hh"
|
||||
|
||||
using namespace Napi;
|
||||
|
||||
StringPolicy::StringPolicy(const std::string name, const std::string &productName)
|
||||
: PreferencesPolicy(name, productName)
|
||||
{
|
||||
}
|
||||
|
||||
Value StringPolicy::getJSValue(Env env, std::string value) const
|
||||
{
|
||||
return String::New(env, value);
|
||||
}
|
||||
|
||||
std::optional<std::string> StringPolicy::read() const
|
||||
{
|
||||
auto pref = CFPreferencesCopyAppValue(key, appID);
|
||||
|
||||
if (pref == NULL)
|
||||
return std::nullopt;
|
||||
|
||||
if (CFGetTypeID(pref) != CFStringGetTypeID())
|
||||
{
|
||||
CFRelease(pref);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
CFIndex length = CFStringGetLength((CFStringRef)pref);
|
||||
CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
|
||||
std::vector<char> buffer(maxSize);
|
||||
|
||||
if (CFStringGetCString((CFStringRef)pref, buffer.data(), maxSize, kCFStringEncodingUTF8))
|
||||
{
|
||||
std::string result(buffer.data());
|
||||
CFRelease(pref);
|
||||
return result;
|
||||
}
|
||||
|
||||
CFRelease(pref);
|
||||
return std::nullopt;
|
||||
}
|
||||
23
src/macos/StringPolicy.hh
Normal file
23
src/macos/StringPolicy.hh
Normal file
@ -0,0 +1,23 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef STRING_POLICY_H
|
||||
#define STRING_POLICY_H
|
||||
|
||||
#include <napi.h>
|
||||
#include "PreferencesPolicy.hh"
|
||||
|
||||
using namespace Napi;
|
||||
|
||||
class StringPolicy : public PreferencesPolicy<std::string>
|
||||
{
|
||||
public:
|
||||
StringPolicy(const std::string name, const std::string &productName);
|
||||
protected:
|
||||
Value getJSValue(Env env, std::string value) const override;
|
||||
std::optional<std::string> read() const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
13
src/main.cc
13
src/main.cc
@ -22,7 +22,7 @@ Value CreateWatcher(const CallbackInfo &info)
|
||||
{
|
||||
auto env = info.Env();
|
||||
|
||||
#ifndef WINDOWS
|
||||
#if !defined(WINDOWS) && !defined(MACOS)
|
||||
throw TypeError::New(env, "Unsupported platform");
|
||||
#endif
|
||||
|
||||
@ -57,18 +57,23 @@ Value CreateWatcher(const CallbackInfo &info)
|
||||
|
||||
auto policyType = std::string(rawPolicyType.As<String>());
|
||||
|
||||
if (policyType == "string")
|
||||
if (policyType == "string") {
|
||||
watcher->AddStringPolicy(rawPolicyName.As<String>());
|
||||
else if (policyType == "number")
|
||||
}
|
||||
else if (policyType == "number") {
|
||||
watcher->AddNumberPolicy(rawPolicyName.As<String>());
|
||||
else
|
||||
} else if (policyType == "boolean") {
|
||||
watcher->AddBooleanPolicy(rawPolicyName.As<String>());
|
||||
} else {
|
||||
throw TypeError::New(env, "Unknown policy type '" + policyType + "'");
|
||||
}
|
||||
}
|
||||
|
||||
watcher->Queue();
|
||||
|
||||
auto result = Object::New(env);
|
||||
result.Set(String::New(env, "dispose"), Function::New(env, DisposeWatcher, "disposeWatcher", watcher));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
28
src/windows/BooleanPolicy.cc
Normal file
28
src/windows/BooleanPolicy.cc
Normal file
@ -0,0 +1,28 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
#include "BooleanPolicy.hh"
|
||||
#include <iostream>
|
||||
|
||||
using namespace Napi;
|
||||
|
||||
BooleanPolicy::BooleanPolicy(const std::string& name, const std::string& productName)
|
||||
: RegistryPolicy(name, productName, {REG_DWORD}) {}
|
||||
|
||||
bool BooleanPolicy::parseRegistryValue(LPBYTE buffer, DWORD bufferSize, DWORD type) const
|
||||
{
|
||||
if (type != REG_DWORD || bufferSize != sizeof(DWORD))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD value = *reinterpret_cast<DWORD*>(buffer);
|
||||
return (value != 0);
|
||||
}
|
||||
|
||||
Value BooleanPolicy::getJSValue(Env env, bool value) const
|
||||
{
|
||||
return Boolean::New(env, value);
|
||||
}
|
||||
25
src/windows/BooleanPolicy.hh
Normal file
25
src/windows/BooleanPolicy.hh
Normal file
@ -0,0 +1,25 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef BOOLEAN_POLICY_H
|
||||
#define BOOLEAN_POLICY_H
|
||||
|
||||
#include <napi.h>
|
||||
#include <windows.h>
|
||||
#include "RegistryPolicy.hh"
|
||||
|
||||
using namespace Napi;
|
||||
|
||||
class BooleanPolicy : public RegistryPolicy<bool>
|
||||
{
|
||||
public:
|
||||
BooleanPolicy(const std::string& name, const std::string &productName);
|
||||
|
||||
protected:
|
||||
bool parseRegistryValue(LPBYTE buffer, DWORD bufferSize, DWORD type) const;
|
||||
Value getJSValue(Env env, bool value) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -8,6 +8,7 @@
|
||||
#include "../PolicyWatcher.hh"
|
||||
#include "StringPolicy.hh"
|
||||
#include "NumberPolicy.hh"
|
||||
#include "BooleanPolicy.hh"
|
||||
|
||||
using namespace Napi;
|
||||
|
||||
@ -38,6 +39,11 @@ void PolicyWatcher::AddNumberPolicy(const std::string name)
|
||||
policies.push_back(std::make_unique<NumberPolicy>(name, vendorName, productName));
|
||||
}
|
||||
|
||||
void PolicyWatcher::AddBooleanPolicy(const std::string name)
|
||||
{
|
||||
policies.push_back(std::make_unique<BooleanPolicy>(name, productName));
|
||||
}
|
||||
|
||||
void PolicyWatcher::OnExecute(Napi::Env env)
|
||||
{
|
||||
if ((handles[0] = CreateEvent(NULL, false, false, NULL)) == NULL)
|
||||
@ -64,15 +70,26 @@ void PolicyWatcher::Execute(const ExecutionProgress &progress)
|
||||
{
|
||||
std::vector<const Policy *> updatedPolicies;
|
||||
|
||||
bool update = false;
|
||||
updatedPolicies.clear();
|
||||
for (auto &policy : policies)
|
||||
{
|
||||
if (policy->refresh())
|
||||
switch (policy->refresh())
|
||||
{
|
||||
case PolicyRefreshResult::Updated:
|
||||
updatedPolicies.push_back(policy.get());
|
||||
update = true;
|
||||
break;
|
||||
case PolicyRefreshResult::Unchanged:
|
||||
updatedPolicies.push_back(policy.get());
|
||||
break;
|
||||
case PolicyRefreshResult::Removed:
|
||||
update = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (first || updatedPolicies.size() > 0)
|
||||
if (first || update)
|
||||
progress.Send(&updatedPolicies[0], updatedPolicies.size());
|
||||
|
||||
first = false;
|
||||
|
||||
@ -24,7 +24,7 @@ public:
|
||||
registryKey("Software\\Policies\\" + vendorName + "\\" + productName),
|
||||
supportedTypes(types) {}
|
||||
|
||||
bool refresh()
|
||||
PolicyRefreshResult refresh()
|
||||
{
|
||||
auto machine = read(HKEY_LOCAL_MACHINE);
|
||||
|
||||
@ -33,21 +33,31 @@ public:
|
||||
if (value != machine)
|
||||
{
|
||||
value = machine;
|
||||
return true;
|
||||
return PolicyRefreshResult::Updated;
|
||||
}
|
||||
|
||||
return false;
|
||||
return PolicyRefreshResult::Unchanged;
|
||||
}
|
||||
|
||||
auto user = read(HKEY_CURRENT_USER);
|
||||
|
||||
// Check for no value or removal
|
||||
if (!user.has_value())
|
||||
{
|
||||
if (!value.has_value())
|
||||
return PolicyRefreshResult::NotSet;
|
||||
|
||||
value.reset();
|
||||
return PolicyRefreshResult::Removed;
|
||||
}
|
||||
|
||||
if (value != user)
|
||||
{
|
||||
value = user;
|
||||
return true;
|
||||
return PolicyRefreshResult::Updated;
|
||||
}
|
||||
|
||||
return false;
|
||||
return PolicyRefreshResult::Unchanged;
|
||||
}
|
||||
|
||||
Value getValue(Env env) const
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user