mirror of
https://github.com/VSCodium/policy-watcher.git
synced 2025-12-10 03:53:55 -06:00
Initial commit
This commit is contained in:
parent
a36186ecb3
commit
c42e9ee946
20
.github/workflows/ci.yml
vendored
Normal file
20
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: ["**"]
|
||||||
|
tags: [v*]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
|
- run: npm install
|
||||||
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/node_modules
|
||||||
|
/build
|
||||||
19
.vscode/c_cpp_properties.json
vendored
Normal file
19
.vscode/c_cpp_properties.json
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Win32",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**",
|
||||||
|
"${workspaceFolder}/node_modules/node-addon-api",
|
||||||
|
"${default}"
|
||||||
|
],
|
||||||
|
"defines": ["_DEBUG"],
|
||||||
|
"windowsSdkVersion": "10.0.18362.0",
|
||||||
|
"compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe",
|
||||||
|
"cStandard": "c17",
|
||||||
|
"cppStandard": "c++17",
|
||||||
|
"intelliSenseMode": "windows-msvc-x64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
72
.vscode/settings.json
vendored
Normal file
72
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"system_error": "cpp",
|
||||||
|
"thread": "cpp",
|
||||||
|
"algorithm": "cpp",
|
||||||
|
"array": "cpp",
|
||||||
|
"atomic": "cpp",
|
||||||
|
"bit": "cpp",
|
||||||
|
"cctype": "cpp",
|
||||||
|
"charconv": "cpp",
|
||||||
|
"chrono": "cpp",
|
||||||
|
"clocale": "cpp",
|
||||||
|
"cmath": "cpp",
|
||||||
|
"compare": "cpp",
|
||||||
|
"concepts": "cpp",
|
||||||
|
"cstddef": "cpp",
|
||||||
|
"cstdint": "cpp",
|
||||||
|
"cstdio": "cpp",
|
||||||
|
"cstdlib": "cpp",
|
||||||
|
"cstring": "cpp",
|
||||||
|
"ctime": "cpp",
|
||||||
|
"cwchar": "cpp",
|
||||||
|
"exception": "cpp",
|
||||||
|
"format": "cpp",
|
||||||
|
"forward_list": "cpp",
|
||||||
|
"functional": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"iomanip": "cpp",
|
||||||
|
"ios": "cpp",
|
||||||
|
"iosfwd": "cpp",
|
||||||
|
"iostream": "cpp",
|
||||||
|
"istream": "cpp",
|
||||||
|
"iterator": "cpp",
|
||||||
|
"limits": "cpp",
|
||||||
|
"list": "cpp",
|
||||||
|
"locale": "cpp",
|
||||||
|
"map": "cpp",
|
||||||
|
"memory": "cpp",
|
||||||
|
"mutex": "cpp",
|
||||||
|
"new": "cpp",
|
||||||
|
"optional": "cpp",
|
||||||
|
"ostream": "cpp",
|
||||||
|
"ratio": "cpp",
|
||||||
|
"sstream": "cpp",
|
||||||
|
"stdexcept": "cpp",
|
||||||
|
"stop_token": "cpp",
|
||||||
|
"streambuf": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"tuple": "cpp",
|
||||||
|
"type_traits": "cpp",
|
||||||
|
"typeinfo": "cpp",
|
||||||
|
"unordered_map": "cpp",
|
||||||
|
"utility": "cpp",
|
||||||
|
"vector": "cpp",
|
||||||
|
"xfacet": "cpp",
|
||||||
|
"xhash": "cpp",
|
||||||
|
"xiosbase": "cpp",
|
||||||
|
"xlocale": "cpp",
|
||||||
|
"xlocbuf": "cpp",
|
||||||
|
"xlocinfo": "cpp",
|
||||||
|
"xlocmes": "cpp",
|
||||||
|
"xlocmon": "cpp",
|
||||||
|
"xlocnum": "cpp",
|
||||||
|
"xloctime": "cpp",
|
||||||
|
"xmemory": "cpp",
|
||||||
|
"xstddef": "cpp",
|
||||||
|
"xstring": "cpp",
|
||||||
|
"xtr1common": "cpp",
|
||||||
|
"xtree": "cpp",
|
||||||
|
"xutility": "cpp"
|
||||||
|
}
|
||||||
|
}
|
||||||
24
.vscode/tasks.json
vendored
Normal file
24
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"script": "build",
|
||||||
|
"group": "build",
|
||||||
|
"problemMatcher": [],
|
||||||
|
"label": "npm: build",
|
||||||
|
"detail": "node-gyp build"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "npm",
|
||||||
|
"script": "rebuild",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [],
|
||||||
|
"label": "npm: rebuild",
|
||||||
|
"detail": "node-gyp rebuild"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
21
README.md
21
README.md
@ -1,14 +1,19 @@
|
|||||||
# Project
|
# vscode-policy-watcher
|
||||||
|
|
||||||
> This repo has been populated by an initial template to help get you started. Please
|
Example usage:
|
||||||
> make sure to update the content to build a great experience for community-building.
|
|
||||||
|
|
||||||
As the maintainer of this project, please make a few updates:
|
```js
|
||||||
|
const createWatcher = require("vscode-policy-watcher");
|
||||||
|
|
||||||
- Improving this README.MD file to provide a great experience
|
createWatcher(
|
||||||
- Updating SUPPORT.MD with content about this project's support experience
|
"CodeOSS",
|
||||||
- Understanding the security reporting process in SECURITY.MD
|
{
|
||||||
- Remove this section from the README
|
UpdateMode: { type: "string" },
|
||||||
|
SCMInputFontSize: { type: "number" },
|
||||||
|
},
|
||||||
|
(update) => console.log(update)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
|||||||
12
SUPPORT.md
12
SUPPORT.md
@ -1,13 +1,3 @@
|
|||||||
# TODO: The maintainer of this repo has not yet edited this file
|
|
||||||
|
|
||||||
**REPO OWNER**: Do you want Customer Service & Support (CSS) support for this product/project?
|
|
||||||
|
|
||||||
- **No CSS support:** Fill out this template with information about how to file issues and get help.
|
|
||||||
- **Yes CSS support:** Fill out an intake form at [aka.ms/onboardsupport](https://aka.ms/onboardsupport). CSS will work with/help you to determine next steps.
|
|
||||||
- **Not sure?** Fill out an intake as though the answer were "Yes". CSS will help you decide.
|
|
||||||
|
|
||||||
*Then remove this first heading from this SUPPORT.MD file before publishing your repo.*
|
|
||||||
|
|
||||||
# Support
|
# Support
|
||||||
|
|
||||||
## How to file issues and get help
|
## How to file issues and get help
|
||||||
@ -22,4 +12,4 @@ CHANNEL. WHERE WILL YOU HELP PEOPLE?**.
|
|||||||
|
|
||||||
## Microsoft Support Policy
|
## Microsoft Support Policy
|
||||||
|
|
||||||
Support for this **PROJECT or PRODUCT** is limited to the resources listed above.
|
Support for this project is limited to the resources listed above.
|
||||||
|
|||||||
44
binding.gyp
Normal file
44
binding.gyp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"target_name": "vscode-policy-watcher",
|
||||||
|
"sources": [
|
||||||
|
"src/main.cc",
|
||||||
|
"src/StringPolicy.cc",
|
||||||
|
"src/NumberPolicy.cc",
|
||||||
|
"src/PolicyWatcher.cc"
|
||||||
|
],
|
||||||
|
"include_dirs": [
|
||||||
|
"<!(node -p \"require('node-addon-api').include_dir\")"
|
||||||
|
],
|
||||||
|
'cflags!': ['-fno-exceptions'],
|
||||||
|
'cflags_cc!': ['-fno-exceptions'],
|
||||||
|
'conditions': [
|
||||||
|
["OS=='win'", {
|
||||||
|
"defines": [
|
||||||
|
"_HAS_EXCEPTIONS=1"
|
||||||
|
],
|
||||||
|
"libraries": [
|
||||||
|
"userenv.lib"
|
||||||
|
],
|
||||||
|
"msvs_settings": {
|
||||||
|
"VCCLCompilerTool": {
|
||||||
|
"ExceptionHandling": 1,
|
||||||
|
'AdditionalOptions': [
|
||||||
|
'/W3',
|
||||||
|
'/Qspectre',
|
||||||
|
'/guard:cf',
|
||||||
|
'-std:c++17'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'VCLinkerTool': {
|
||||||
|
'AdditionalOptions': [
|
||||||
|
'/guard:cf'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
31
index.d.ts
vendored
Normal file
31
index.d.ts
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
interface Watcher {
|
||||||
|
dispose(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
type StringPolicy = { type: "string" };
|
||||||
|
type NumberPolicy = { type: "number" };
|
||||||
|
|
||||||
|
export interface Policies {
|
||||||
|
[policyName: string]: StringPolicy | NumberPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PolicyUpdate<T extends Policies> = {
|
||||||
|
[K in keyof T]:
|
||||||
|
| undefined
|
||||||
|
| (T[K] extends StringPolicy
|
||||||
|
? string
|
||||||
|
: T[K] extends NumberPolicy
|
||||||
|
? number
|
||||||
|
: never);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function createWatcher<T extends Policies>(
|
||||||
|
productName: string,
|
||||||
|
policies: T,
|
||||||
|
onDidChange: (update: PolicyUpdate<T>) => void
|
||||||
|
): Watcher;
|
||||||
17
index.js
Normal file
17
index.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
exports.createWatcher = require('bindings')('vscode-policy-watcher');
|
||||||
|
|
||||||
|
if (require.main === module) {
|
||||||
|
exports.createWatcher(
|
||||||
|
'CodeOSS',
|
||||||
|
{
|
||||||
|
UpdateMode: { type: 'string' },
|
||||||
|
SCMInputFontSize: { type: 'number' },
|
||||||
|
},
|
||||||
|
msg => console.log(msg)
|
||||||
|
);
|
||||||
|
}
|
||||||
1904
package-lock.json
generated
Normal file
1904
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
23
package.json
Normal file
23
package.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "vscode-policy-watcher",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "node-gyp build",
|
||||||
|
"rebuild": "node-gyp rebuild"
|
||||||
|
},
|
||||||
|
"author": "João Moreno",
|
||||||
|
"license": "MIT",
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"types": "index.d.ts",
|
||||||
|
"dependencies": {
|
||||||
|
"bindings": "^1.5.0",
|
||||||
|
"node-addon-api": "*"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"node-gyp": "^9.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/NumberPolicy.cc
Normal file
21
src/NumberPolicy.cc
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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)
|
||||||
|
: RegistryPolicy(name, productName, REG_QWORD) {}
|
||||||
|
|
||||||
|
long long NumberPolicy::parseRegistryValue(LPBYTE buffer, DWORD bufferSize) const
|
||||||
|
{
|
||||||
|
return *reinterpret_cast<long long *>(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
Value NumberPolicy::getJSValue(Env env, long long value) const
|
||||||
|
{
|
||||||
|
return Number::New(env, value);
|
||||||
|
}
|
||||||
25
src/NumberPolicy.hh
Normal file
25
src/NumberPolicy.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 NUMBER_POLICY_H
|
||||||
|
#define NUMBER_POLICY_H
|
||||||
|
|
||||||
|
#include <napi.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include "RegistryPolicy.hh"
|
||||||
|
|
||||||
|
using namespace Napi;
|
||||||
|
|
||||||
|
class NumberPolicy : public RegistryPolicy<long long>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NumberPolicy(const std::string name, const std::string &productName);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
long long parseRegistryValue(LPBYTE buffer, DWORD bufferSize) const;
|
||||||
|
Value getJSValue(Env env, long long value) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
24
src/Policy.hh
Normal file
24
src/Policy.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 POLICY_H
|
||||||
|
#define POLICY_H
|
||||||
|
|
||||||
|
#include <napi.h>
|
||||||
|
|
||||||
|
using namespace Napi;
|
||||||
|
|
||||||
|
class Policy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool refresh() = 0;
|
||||||
|
virtual Value getValue(Env env) const = 0;
|
||||||
|
const std::string name;
|
||||||
|
|
||||||
|
Policy(const std::string name)
|
||||||
|
: name(name) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
89
src/PolicyWatcher.cc
Normal file
89
src/PolicyWatcher.cc
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "PolicyWatcher.hh"
|
||||||
|
|
||||||
|
using namespace Napi;
|
||||||
|
|
||||||
|
PolicyWatcher::PolicyWatcher(Function &okCallback, std::vector<std::unique_ptr<Policy>> _policies)
|
||||||
|
: AsyncProgressQueueWorker(okCallback),
|
||||||
|
policies(std::move(_policies))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PolicyWatcher::~PolicyWatcher()
|
||||||
|
{
|
||||||
|
UnregisterGPNotification(handles[2]);
|
||||||
|
UnregisterGPNotification(handles[3]);
|
||||||
|
CloseHandle(handles[0]);
|
||||||
|
CloseHandle(handles[1]);
|
||||||
|
CloseHandle(handles[2]);
|
||||||
|
CloseHandle(handles[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolicyWatcher::OnExecute(Napi::Env env)
|
||||||
|
{
|
||||||
|
if ((handles[0] = CreateEvent(NULL, false, false, NULL)) == NULL)
|
||||||
|
return SetError("Failed to create exit event");
|
||||||
|
if ((handles[1] = CreateEvent(NULL, false, false, NULL)) == NULL)
|
||||||
|
return SetError("Failed to create dispose event");
|
||||||
|
if ((handles[2] = CreateEvent(NULL, false, false, NULL)) == NULL)
|
||||||
|
return SetError("Failed to create machine GP event");
|
||||||
|
if ((handles[3] = CreateEvent(NULL, false, false, NULL)) == NULL)
|
||||||
|
return SetError("Failed to create user GP event");
|
||||||
|
if (!RegisterGPNotification(handles[2], TRUE))
|
||||||
|
return SetError("Failed to register machine GP event");
|
||||||
|
if (!RegisterGPNotification(handles[3], FALSE))
|
||||||
|
return SetError("Failed to register user GP event");
|
||||||
|
|
||||||
|
AsyncProgressQueueWorker::OnExecute(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolicyWatcher::Execute(const ExecutionProgress &progress)
|
||||||
|
{
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
std::vector<const Policy *> updatedPolicies;
|
||||||
|
|
||||||
|
for (auto &policy : policies)
|
||||||
|
{
|
||||||
|
if (policy->refresh())
|
||||||
|
{
|
||||||
|
updatedPolicies.push_back(policy.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first || updatedPolicies.size() > 0)
|
||||||
|
progress.Send(&updatedPolicies[0], updatedPolicies.size());
|
||||||
|
|
||||||
|
first = false;
|
||||||
|
|
||||||
|
auto dwResult = WaitForMultipleObjects(4, handles, FALSE, INFINITE);
|
||||||
|
|
||||||
|
if (dwResult == WAIT_FAILED || (dwResult - WAIT_OBJECT_0) == 0 || (dwResult - WAIT_OBJECT_0) == 1 /* someone called dispose() */)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolicyWatcher::OnOK() {}
|
||||||
|
void PolicyWatcher::OnError() {}
|
||||||
|
|
||||||
|
void PolicyWatcher::OnProgress(const Policy *const *policies, size_t count)
|
||||||
|
{
|
||||||
|
HandleScope scope(Env());
|
||||||
|
auto result = Object::New(Env());
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
SetEvent(handles[1]);
|
||||||
|
}
|
||||||
35
src/PolicyWatcher.hh
Normal file
35
src/PolicyWatcher.hh
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef POLICY_WATCHER_H
|
||||||
|
#define POLICY_WATCHER_H
|
||||||
|
|
||||||
|
#include <napi.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <userenv.h>
|
||||||
|
#include <vector>
|
||||||
|
#include "Policy.hh"
|
||||||
|
|
||||||
|
using namespace Napi;
|
||||||
|
|
||||||
|
class PolicyWatcher : public AsyncProgressQueueWorker<const Policy *>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PolicyWatcher(Function &okCallback, std::vector<std::unique_ptr<Policy>> _policies);
|
||||||
|
~PolicyWatcher();
|
||||||
|
|
||||||
|
void OnExecute(Napi::Env env);
|
||||||
|
void Execute(const ExecutionProgress &progress);
|
||||||
|
void OnOK();
|
||||||
|
void OnError();
|
||||||
|
void OnProgress(const Policy *const *policies, size_t count);
|
||||||
|
void Dispose();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::unique_ptr<Policy>> policies;
|
||||||
|
HANDLE handles[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
89
src/RegistryPolicy.hh
Normal file
89
src/RegistryPolicy.hh
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef REGISTRY_POLICY_H
|
||||||
|
#define REGISTRY_POLICY_H
|
||||||
|
|
||||||
|
#include <napi.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <optional>
|
||||||
|
#include "Policy.hh"
|
||||||
|
|
||||||
|
using namespace Napi;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class RegistryPolicy : public Policy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RegistryPolicy(const std::string name, const std::string &productName, const DWORD regType)
|
||||||
|
: Policy(name),
|
||||||
|
registryKey("Software\\Policies\\Microsoft\\" + productName),
|
||||||
|
regType(regType) {}
|
||||||
|
|
||||||
|
bool refresh()
|
||||||
|
{
|
||||||
|
auto machine = read(HKEY_LOCAL_MACHINE);
|
||||||
|
|
||||||
|
if (machine.has_value())
|
||||||
|
{
|
||||||
|
if (value != machine)
|
||||||
|
{
|
||||||
|
value = machine;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto user = read(HKEY_CURRENT_USER);
|
||||||
|
|
||||||
|
if (value != user)
|
||||||
|
{
|
||||||
|
value = user;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value getValue(Env env) const
|
||||||
|
{
|
||||||
|
if (!value.has_value())
|
||||||
|
return env.Undefined();
|
||||||
|
|
||||||
|
return getJSValue(env, value.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual T parseRegistryValue(LPBYTE buffer, DWORD bufferSize) const = 0;
|
||||||
|
virtual Value getJSValue(Env env, T value) const = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::string registryKey;
|
||||||
|
const DWORD regType;
|
||||||
|
std::optional<T> value;
|
||||||
|
|
||||||
|
std::optional<T> read(HKEY root)
|
||||||
|
{
|
||||||
|
HKEY hKey;
|
||||||
|
|
||||||
|
if (ERROR_SUCCESS != RegOpenKeyEx(root, registryKey.c_str(), 0, KEY_READ, &hKey))
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
BYTE buffer[1024];
|
||||||
|
DWORD bufferSize = sizeof(buffer);
|
||||||
|
DWORD type;
|
||||||
|
|
||||||
|
auto readResult = RegQueryValueEx(hKey, name.c_str(), 0, &type, buffer, &bufferSize);
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
|
||||||
|
if (ERROR_SUCCESS != readResult || type != regType)
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
return std::optional<T>{parseRegistryValue(buffer, bufferSize)};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
21
src/StringPolicy.cc
Normal file
21
src/StringPolicy.cc
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* 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)
|
||||||
|
: RegistryPolicy(name, productName, REG_SZ) {}
|
||||||
|
|
||||||
|
std::string StringPolicy::parseRegistryValue(LPBYTE buffer, DWORD bufferSize) const
|
||||||
|
{
|
||||||
|
return std::string(reinterpret_cast<char *>(buffer), bufferSize - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Value StringPolicy::getJSValue(Env env, std::string value) const
|
||||||
|
{
|
||||||
|
return String::New(env, value);
|
||||||
|
}
|
||||||
25
src/StringPolicy.hh
Normal file
25
src/StringPolicy.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 STRING_POLICY_H
|
||||||
|
#define STRING_POLICY_H
|
||||||
|
|
||||||
|
#include <napi.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include "RegistryPolicy.hh"
|
||||||
|
|
||||||
|
using namespace Napi;
|
||||||
|
|
||||||
|
class StringPolicy : public RegistryPolicy<std::string>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StringPolicy(const std::string name, const std::string &productName);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string parseRegistryValue(LPBYTE buffer, DWORD bufferSize) const;
|
||||||
|
Value getJSValue(Env env, std::string value) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
77
src/main.cc
Normal file
77
src/main.cc
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <napi.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Policy.hh"
|
||||||
|
#include "StringPolicy.hh"
|
||||||
|
#include "NumberPolicy.hh"
|
||||||
|
#include "PolicyWatcher.hh"
|
||||||
|
|
||||||
|
using namespace Napi;
|
||||||
|
|
||||||
|
Value DisposeWatcher(const CallbackInfo &info)
|
||||||
|
{
|
||||||
|
auto watcher = (PolicyWatcher *)info.Data();
|
||||||
|
watcher->Dispose();
|
||||||
|
return info.Env().Null();
|
||||||
|
}
|
||||||
|
|
||||||
|
Value CreateWatcher(const CallbackInfo &info)
|
||||||
|
{
|
||||||
|
auto env = info.Env();
|
||||||
|
|
||||||
|
if (info.Length() < 3)
|
||||||
|
throw TypeError::New(env, "Expected 3 arguments");
|
||||||
|
else if (!info[0].IsString())
|
||||||
|
throw TypeError::New(env, "Expected first arg to be string");
|
||||||
|
else if (!info[1].IsObject())
|
||||||
|
throw TypeError::New(env, "Expected second arg to be object");
|
||||||
|
else if (!info[2].IsFunction())
|
||||||
|
throw TypeError::New(env, "Expected third arg to be function");
|
||||||
|
|
||||||
|
auto productName = info[0].As<String>();
|
||||||
|
auto rawPolicies = info[1].As<Object>();
|
||||||
|
auto policies = std::vector<std::unique_ptr<Policy>>();
|
||||||
|
|
||||||
|
for (auto const &item : rawPolicies)
|
||||||
|
{
|
||||||
|
auto rawPolicyName = item.first.As<String>();
|
||||||
|
auto rawPolicyValue = static_cast<Value>(item.second);
|
||||||
|
|
||||||
|
if (!rawPolicyValue.IsObject())
|
||||||
|
throw TypeError::New(env, "Expected policy to be object");
|
||||||
|
|
||||||
|
auto rawPolicy = rawPolicyValue.As<Object>();
|
||||||
|
auto rawPolicyType = rawPolicy.Get("type");
|
||||||
|
|
||||||
|
if (!rawPolicyType.IsString())
|
||||||
|
throw TypeError::New(env, "Expected policy type to be string");
|
||||||
|
|
||||||
|
auto policyType = std::string(rawPolicyType.As<String>());
|
||||||
|
|
||||||
|
if (policyType == "string")
|
||||||
|
policies.push_back(std::make_unique<StringPolicy>(rawPolicyName.As<String>(), productName));
|
||||||
|
else if (policyType == "number")
|
||||||
|
policies.push_back(std::make_unique<NumberPolicy>(rawPolicyName.As<String>(), productName));
|
||||||
|
else
|
||||||
|
throw TypeError::New(env, "Unknown policy type '" + policyType + "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto watcher = new PolicyWatcher(info[2].As<Function>(), std::move(policies));
|
||||||
|
watcher->Queue();
|
||||||
|
|
||||||
|
auto result = Object::New(env);
|
||||||
|
result.Set(String::New(env, "dispose"), Function::New(env, DisposeWatcher, "disposeWatcher", watcher));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object Init(Env env, Object exports)
|
||||||
|
{
|
||||||
|
return Function::New(env, CreateWatcher, "createWatcher");
|
||||||
|
}
|
||||||
|
|
||||||
|
NODE_API_MODULE(vscodepolicy, Init)
|
||||||
Loading…
x
Reference in New Issue
Block a user