summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
authorEgor Tensin <egor@tensin.name>2026-06-13 00:36:59 +0200
committerEgor Tensin <egor@tensin.name>2026-06-13 00:39:55 +0200
commit190ff781eaee33e7a61aab44fc4133718cc0515b (patch)
tree469cedfc87734589a4e9a0102f69324b9edb8f16 /src
parentcmake: upgrade minimum version (diff)
downloadprivilege-check-190ff781eaee33e7a61aab44fc4133718cc0515b.tar.gz
privilege-check-190ff781eaee33e7a61aab44fc4133718cc0515b.zip
add .clang-format
Diffstat (limited to 'src')
-rw-r--r--src/cmd_line.hpp74
-rw-r--r--src/error.hpp35
-rw-r--r--src/handle.hpp45
-rw-r--r--src/main.cpp315
-rw-r--r--src/os.hpp36
-rw-r--r--src/process.cpp72
-rw-r--r--src/process.hpp40
-rw-r--r--src/resource.hpp25
-rw-r--r--src/sid.cpp90
-rw-r--r--src/sid.hpp15
-rw-r--r--src/string.hpp209
-rw-r--r--src/token.cpp227
-rw-r--r--src/token.hpp48
13 files changed, 551 insertions, 680 deletions
diff --git a/src/cmd_line.hpp b/src/cmd_line.hpp
index ae96ed5..b1eb2a5 100644
--- a/src/cmd_line.hpp
+++ b/src/cmd_line.hpp
@@ -8,28 +8,26 @@
#include "error.hpp"
#include "string.hpp"
+/* clang-format off */
#include <windows.h>
#include <shellapi.h>
+/* clang-format on */
#include <cstddef>
-
#include <memory>
-#include <stdexcept>
#include <sstream>
+#include <stdexcept>
#include <string>
#include <utility>
#include <vector>
-class CommandLine
-{
+class CommandLine {
public:
- static CommandLine query()
- {
+ static CommandLine query() {
return build_from_string(GetCommandLine());
}
- static CommandLine build_from_main(int argc, wchar_t* argv[])
- {
+ static CommandLine build_from_main(int argc, wchar_t* argv[]) {
if (argc < 1)
throw std::range_error{"invalid argc value"};
@@ -48,33 +46,27 @@ public:
CommandLine() = default;
- bool has_argv0() const
- {
+ bool has_argv0() const {
return !argv0.empty();
}
- std::wstring get_argv0() const
- {
+ std::wstring get_argv0() const {
return argv0;
}
- std::wstring escape_argv0() const
- {
+ std::wstring escape_argv0() const {
return escape(get_argv0());
}
- bool has_args() const
- {
+ bool has_args() const {
return !get_args().empty();
}
- const std::vector<std::wstring>& get_args() const
- {
+ const std::vector<std::wstring>& get_args() const {
return args;
}
- std::vector<std::wstring> escape_args() const
- {
+ std::vector<std::wstring> escape_args() const {
std::vector<std::wstring> safe;
safe.reserve(args.size());
for (const auto& arg : args)
@@ -82,15 +74,15 @@ public:
return safe;
}
- static constexpr wchar_t sep() { return L' '; }
+ static constexpr wchar_t sep() {
+ return L' ';
+ }
- std::wstring join_args() const
- {
+ std::wstring join_args() const {
return string::join(sep(), escape_args());
}
- std::wstring join() const
- {
+ std::wstring join() const {
if (!has_argv0())
throw std::logic_error{"argv[0] isn't defined"};
std::wostringstream oss;
@@ -101,8 +93,7 @@ public:
}
private:
- static CommandLine build_from_string(std::wstring src)
- {
+ static CommandLine build_from_string(std::wstring src) {
string::trim(src);
if (src.empty())
return {};
@@ -127,8 +118,7 @@ private:
return {std::move(argv0), std::move(args)};
}
- inline std::wstring escape_for_cmd(const std::wstring& arg)
- {
+ inline std::wstring escape_for_cmd(const std::wstring& arg) {
static constexpr auto escape_symbol = L'^';
static constexpr auto dangerous_symbols = L"!\"%&()<>^|";
@@ -137,29 +127,25 @@ private:
return safe;
}
- static std::wstring escape(const std::wstring& arg)
- {
+ static std::wstring escape(const std::wstring& arg) {
std::wstring safe;
safe.reserve(arg.length() + 2);
safe.push_back(L'"');
- for (auto it = arg.cbegin(); it != arg.cend(); ++it)
- {
+ for (auto it = arg.cbegin(); it != arg.cend(); ++it) {
std::size_t numof_backslashes = 0;
for (; it != arg.cend() && *it == L'\\'; ++it)
++numof_backslashes;
- if (it == arg.cend())
- {
+ if (it == arg.cend()) {
safe.reserve(safe.capacity() + numof_backslashes);
safe.append(2 * numof_backslashes, L'\\');
break;
}
- switch (*it)
- {
+ switch (*it) {
case L'"':
safe.reserve(safe.capacity() + numof_backslashes + 1);
safe.append(2 * numof_backslashes + 1, L'\\');
@@ -177,22 +163,16 @@ private:
return safe;
}
- struct LocalDelete
- {
- void operator()(wchar_t* argv[]) const
- {
+ struct LocalDelete {
+ void operator()(wchar_t* argv[]) const {
LocalFree(argv);
}
};
- CommandLine(std::vector<std::wstring>&& args)
- : args{std::move(args)}
- { }
+ CommandLine(std::vector<std::wstring>&& args) : args{std::move(args)} {}
CommandLine(std::wstring&& argv0, std::vector<std::wstring>&& args = {})
- : argv0{std::move(argv0)}
- , args{std::move(args)}
- { }
+ : argv0{std::move(argv0)}, args{std::move(args)} {}
const std::wstring argv0;
const std::vector<std::wstring> args;
diff --git a/src/error.hpp b/src/error.hpp
index 04ec8c9..8a0778c 100644
--- a/src/error.hpp
+++ b/src/error.hpp
@@ -12,26 +12,23 @@
typedef std::system_error Error;
-namespace error
-{
- inline Error make(const char* function_name)
- {
- const auto ec = GetLastError();
- return {static_cast<int>(ec), std::system_category(), function_name};
- }
+namespace error {
- inline void raise(const char* function_name)
- {
- throw make(function_name);
- }
+inline Error make(const char* function_name) {
+ const auto ec = GetLastError();
+ return {static_cast<int>(ec), std::system_category(), function_name};
+}
- inline void report(const std::exception& e)
- {
- MessageBoxA(NULL, e.what(), NULL, MB_OK);
- }
+inline void raise(const char* function_name) {
+ throw make(function_name);
+}
- inline int get_code(const Error& e)
- {
- return e.code().value();
- }
+inline void report(const std::exception& e) {
+ MessageBoxA(NULL, e.what(), NULL, MB_OK);
}
+
+inline int get_code(const Error& e) {
+ return e.code().value();
+}
+
+} // namespace error
diff --git a/src/handle.hpp b/src/handle.hpp
index 4bc0a97..5839594 100644
--- a/src/handle.hpp
+++ b/src/handle.hpp
@@ -8,51 +8,41 @@
#include <windows.h>
#include <cassert>
-
#include <memory>
#include <utility>
-class Handle
-{
+class Handle {
public:
Handle() = default;
- explicit Handle(HANDLE raw)
- : impl{raw}
- { }
+ explicit Handle(HANDLE raw) : impl{raw} {}
- Handle(Handle&& other) noexcept
- {
+ Handle(Handle&& other) noexcept {
swap(other);
}
- Handle& operator=(Handle other) noexcept
- {
+ Handle& operator=(Handle other) noexcept {
swap(other);
return *this;
}
- void swap(Handle& other) noexcept
- {
+ void swap(Handle& other) noexcept {
using std::swap;
swap(impl, other.impl);
}
- operator HANDLE() const
- {
+ operator HANDLE() const {
return impl.get();
}
private:
- struct Close
- {
- void operator()(HANDLE raw) const
- {
+ struct Close {
+ void operator()(HANDLE raw) const {
if (raw == NULL || raw == INVALID_HANDLE_VALUE)
return;
const auto ret = CloseHandle(raw);
assert(ret);
- (void) ret;
+ (void)ret;
}
};
@@ -61,16 +51,15 @@ private:
Handle(const Handle&) = delete;
};
-inline void swap(Handle& a, Handle& b) noexcept
-{
+inline void swap(Handle& a, Handle& b) noexcept {
a.swap(b);
}
-namespace std
-{
- template <>
- inline void swap(Handle& a, Handle& b) noexcept
- {
- a.swap(b);
- }
+namespace std {
+
+template <>
+inline void swap(Handle& a, Handle& b) noexcept {
+ a.swap(b);
}
+
+} // namespace std
diff --git a/src/main.cpp b/src/main.cpp
index 4065a5e..8b81587 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -11,242 +11,189 @@
#include "sid.hpp"
#include "token.hpp"
-#include <commctrl.h>
+/* clang-format off */
#include <windows.h>
+#include <commctrl.h>
#include <windowsx.h>
+/* clang-format on */
#include <exception>
#include <string>
#if defined(_MSC_VER)
-#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#pragma comment( \
+ linker, \
+ "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
-namespace
-{
- HWND get_dialog_item(HWND wnd, int id)
- {
- const auto lbl = GetDlgItem(wnd, id);
- if (lbl == NULL)
- error::raise("GetDlgItem");
- return lbl;
- }
+namespace {
- bool is_administrator()
- {
- auto token = token::open_for_current_process(
- token::permissions::query() | token::permissions::duplicate());
- if (!token::get_linked(token))
- token = token::get_for_identification(token);
+HWND get_dialog_item(HWND wnd, int id) {
+ const auto lbl = GetDlgItem(wnd, id);
+ if (lbl == NULL)
+ error::raise("GetDlgItem");
+ return lbl;
+}
- return token::check_belongs(token, sid::builtin_administrators());
- }
+bool is_administrator() {
+ auto token = token::open_for_current_process(token::permissions::query() |
+ token::permissions::duplicate());
+ if (!token::get_linked(token))
+ token = token::get_for_identification(token);
- bool is_run_as_administrator()
- {
- return token::check_belongs(token::dumb(), sid::builtin_administrators());
- }
+ return token::check_belongs(token, sid::builtin_administrators());
+}
- bool is_elevated()
- {
- return token::query_elevation(token::open_for_current_process());
- }
+bool is_run_as_administrator() {
+ return token::check_belongs(token::dumb(), sid::builtin_administrators());
+}
- void decorate_elevate_button(HWND wnd, bool decorate)
- {
- const auto btn = get_dialog_item(wnd, IDC_BUTTON_ELEVATE);
- Button_SetElevationRequiredState(btn, !decorate);
- }
+bool is_elevated() {
+ return token::query_elevation(token::open_for_current_process());
+}
- DWORD get_integrity_level()
- {
- return token::query_integrity_level(token::open_for_current_process());
- }
+void decorate_elevate_button(HWND wnd, bool decorate) {
+ const auto btn = get_dialog_item(wnd, IDC_BUTTON_ELEVATE);
+ Button_SetElevationRequiredState(btn, !decorate);
+}
- std::wstring get_integrity_level_as_string()
- {
- return token::integrity_level_to_string(get_integrity_level());
- }
+DWORD get_integrity_level() {
+ return token::query_integrity_level(token::open_for_current_process());
+}
- HWND get_label(HWND wnd, int id)
- {
- return get_dialog_item(wnd, id);
- }
+std::wstring get_integrity_level_as_string() {
+ return token::integrity_level_to_string(get_integrity_level());
+}
- void set_label(HWND wnd, int id, bool val)
- {
- SetWindowTextW(get_label(wnd, id), val ? L"True" : L"False");
- }
+HWND get_label(HWND wnd, int id) {
+ return get_dialog_item(wnd, id);
+}
+
+void set_label(HWND wnd, int id, bool val) {
+ SetWindowTextW(get_label(wnd, id), val ? L"True" : L"False");
+}
+
+void set_label(HWND wnd, int id, const wchar_t* s) {
+ SetWindowTextW(get_label(wnd, id), s);
+}
- void set_label(HWND wnd, int id, const wchar_t* s)
- {
- SetWindowTextW(get_label(wnd, id), s);
+void set_label(HWND wnd, int id, const std::wstring& s) {
+ SetWindowTextW(get_label(wnd, id), s.c_str());
+}
+
+BOOL on_init_dialog(HWND wnd, HWND, LPARAM) {
+ try {
+ set_label(wnd, IDC_ADMINISTRATOR, is_administrator());
+ } catch (const Error& e) {
+ set_label(wnd, IDC_ADMINISTRATOR, L"N/A");
+ error::report(e);
}
- void set_label(HWND wnd, int id, const std::wstring& s)
- {
- SetWindowTextW(get_label(wnd, id), s.c_str());
+ try {
+ set_label(wnd, IDC_RUN_AS_ADMINISTRATOR, is_run_as_administrator());
+ } catch (const Error& e) {
+ set_label(wnd, IDC_RUN_AS_ADMINISTRATOR, L"N/A");
+ error::report(e);
}
- BOOL on_init_dialog(HWND wnd, HWND, LPARAM)
- {
- try
- {
- set_label(wnd, IDC_ADMINISTRATOR, is_administrator());
- }
- catch (const Error& e)
- {
- set_label(wnd, IDC_ADMINISTRATOR, L"N/A");
+ if (os::is_vista_or_later()) {
+ try {
+ const auto elevated = is_elevated();
+ set_label(wnd, IDC_ELEVATED, elevated);
+ decorate_elevate_button(wnd, elevated);
+ } catch (const Error& e) {
+ set_label(wnd, IDC_ELEVATED, L"N/A");
error::report(e);
}
- try
- {
- set_label(wnd, IDC_RUN_AS_ADMINISTRATOR, is_run_as_administrator());
- }
- catch (const Error& e)
- {
- set_label(wnd, IDC_RUN_AS_ADMINISTRATOR, L"N/A");
+ try {
+ set_label(wnd, IDC_INTEGRITY_LEVEL, get_integrity_level_as_string());
+ } catch (const Error& e) {
+ set_label(wnd, IDC_INTEGRITY_LEVEL, L"N/A");
error::report(e);
}
+ } else {
+ set_label(wnd, IDC_ELEVATED, L"N/A");
+ set_label(wnd, IDC_INTEGRITY_LEVEL, L"N/A");
+ }
- if (os::is_vista_or_later())
- {
- try
- {
- const auto elevated = is_elevated();
- set_label(wnd, IDC_ELEVATED, elevated);
- decorate_elevate_button(wnd, elevated);
- }
- catch (const Error& e)
- {
- set_label(wnd, IDC_ELEVATED, L"N/A");
- error::report(e);
- }
+ return TRUE;
+}
- try
- {
- set_label(wnd, IDC_INTEGRITY_LEVEL, get_integrity_level_as_string());
- }
- catch (const Error& e)
- {
- set_label(wnd, IDC_INTEGRITY_LEVEL, L"N/A");
- error::report(e);
- }
- }
- else
- {
- set_label(wnd, IDC_ELEVATED, L"N/A");
- set_label(wnd, IDC_INTEGRITY_LEVEL, L"N/A");
- }
+void report_already_elevated(HWND wnd) {
+ MessageBoxW(wnd,
+ resource::load_string(IDS_ALREADY_ELEVATED_TEXT).c_str(),
+ resource::load_string(IDS_ALREADY_ELEVATED_CAPTION).c_str(),
+ MB_OK);
+}
- return TRUE;
- }
+void on_button_elevate_click(HWND wnd) {
+ bool as_admin = false;
- void report_already_elevated(HWND wnd)
- {
- MessageBoxW(wnd,
- resource::load_string(IDS_ALREADY_ELEVATED_TEXT).c_str(),
- resource::load_string(IDS_ALREADY_ELEVATED_CAPTION).c_str(),
- MB_OK);
+ try {
+ as_admin = is_run_as_administrator();
+ } catch (const Error& e) {
+ error::report(e);
+ return;
}
- void on_button_elevate_click(HWND wnd)
- {
- bool as_admin = false;
+ if (as_admin) {
+ report_already_elevated(wnd);
+ return;
+ }
- try
- {
- as_admin = is_run_as_administrator();
- }
- catch (const Error& e)
- {
+ try {
+ process::runas_self(wnd);
+ } catch (const Error& e) {
+ if (error::get_code(e) != ERROR_CANCELLED)
error::report(e);
- return;
- }
-
- if (as_admin)
- {
- report_already_elevated(wnd);
- return;
- }
-
- try
- {
- process::runas_self(wnd);
- }
- catch (const Error& e)
- {
- if (error::get_code(e) != ERROR_CANCELLED)
- error::report(e);
- return;
- }
-
- EndDialog(wnd, 1);
+ return;
}
- void on_command(HWND wnd, int id, HWND, unsigned int)
- {
- switch (id)
- {
- case IDC_BUTTON_ELEVATE:
- on_button_elevate_click(wnd);
- break;
+ EndDialog(wnd, 1);
+}
- case IDOK:
- case IDCANCEL:
- EndDialog(wnd, 0);
- break;
- }
- }
+void on_command(HWND wnd, int id, HWND, unsigned int) {
+ switch (id) {
+ case IDC_BUTTON_ELEVATE:
+ on_button_elevate_click(wnd);
+ break;
- void on_close(HWND wnd)
- {
- EndDialog(wnd, 0);
+ case IDOK:
+ case IDCANCEL:
+ EndDialog(wnd, 0);
+ break;
}
+}
- INT_PTR CALLBACK dialog_main(
- HWND wnd,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam)
- {
- switch (msg)
- {
- HANDLE_MSG(wnd, WM_INITDIALOG, on_init_dialog);
- HANDLE_MSG(wnd, WM_COMMAND, on_command);
- HANDLE_MSG(wnd, WM_CLOSE, on_close);
+void on_close(HWND wnd) {
+ EndDialog(wnd, 0);
+}
- default:
- return FALSE;
- }
+INT_PTR CALLBACK dialog_main(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+ switch (msg) {
+ HANDLE_MSG(wnd, WM_INITDIALOG, on_init_dialog);
+ HANDLE_MSG(wnd, WM_COMMAND, on_command);
+ HANDLE_MSG(wnd, WM_CLOSE, on_close);
+
+ default:
+ return FALSE;
}
}
-int APIENTRY wWinMain(
- HINSTANCE instance,
- HINSTANCE,
- wchar_t*,
- int)
-{
- try
- {
- const auto ret = DialogBoxW(
- instance,
- MAKEINTRESOURCE(IDD_MAINDIALOG),
- NULL,
- dialog_main);
+} // namespace
+
+int APIENTRY wWinMain(HINSTANCE instance, HINSTANCE, wchar_t*, int) {
+ try {
+ const auto ret = DialogBoxW(instance, MAKEINTRESOURCE(IDD_MAINDIALOG), NULL, dialog_main);
- switch (ret)
- {
+ switch (ret) {
case -1:
error::report(error::make("DialogBoxW"));
default:
return static_cast<int>(ret);
}
- }
- catch (const std::exception& e)
- {
+ } catch (const std::exception& e) {
error::report(e);
return 1;
}
diff --git a/src/os.hpp b/src/os.hpp
index f6f169f..1ec023e 100644
--- a/src/os.hpp
+++ b/src/os.hpp
@@ -9,27 +9,25 @@
#include <windows.h>
-namespace os
-{
- inline OSVERSIONINFOW get_version_info()
- {
- OSVERSIONINFOW info;
- ZeroMemory(&info, sizeof(info));
- info.dwOSVersionInfoSize = sizeof(info);
+namespace os {
- if (!GetVersionExW(&info))
- error::raise("GetVersionExW");
+inline OSVERSIONINFOW get_version_info() {
+ OSVERSIONINFOW info;
+ ZeroMemory(&info, sizeof(info));
+ info.dwOSVersionInfoSize = sizeof(info);
- return info;
- }
+ if (!GetVersionExW(&info))
+ error::raise("GetVersionExW");
- inline bool is_vista_or_later(const OSVERSIONINFOW& info)
- {
- return info.dwMajorVersion >= 6;
- }
+ return info;
+}
+
+inline bool is_vista_or_later(const OSVERSIONINFOW& info) {
+ return info.dwMajorVersion >= 6;
+}
- inline bool is_vista_or_later()
- {
- return is_vista_or_later(get_version_info());
- }
+inline bool is_vista_or_later() {
+ return is_vista_or_later(get_version_info());
}
+
+} // namespace os
diff --git a/src/process.cpp b/src/process.cpp
index a2eddc0..b71bff0 100644
--- a/src/process.cpp
+++ b/src/process.cpp
@@ -3,60 +3,54 @@
// For details, see https://github.com/egor-tensin/privilege-check.
// Distributed under the MIT License.
+#include "process.hpp"
+
#include "cmd_line.hpp"
#include "error.hpp"
-#include "process.hpp"
+/* clang-format off */
#include <windows.h>
#include <shellapi.h>
+/* clang-format on */
#include <array>
#include <string>
-namespace process
-{
- std::wstring get_executable_path()
- {
- static constexpr DWORD max_path = MAX_PATH;
+namespace process {
- std::array<wchar_t, max_path> buf;
+std::wstring get_executable_path() {
+ static constexpr DWORD max_path = MAX_PATH;
- const auto ret = GetModuleFileNameW(NULL, buf.data(), max_path);
+ std::array<wchar_t, max_path> buf;
- if (ret != ERROR_SUCCESS)
- error::raise("GetModuleFileNameW");
+ const auto ret = GetModuleFileNameW(NULL, buf.data(), max_path);
- return buf.data();
- }
+ if (ret != ERROR_SUCCESS)
+ error::raise("GetModuleFileNameW");
- void runas(
- const CommandLine& cmd_line,
- HWND hwnd,
- int nShow)
- {
- const auto exe_path = cmd_line.has_argv0()
- ? cmd_line.get_argv0()
- : get_executable_path();
+ return buf.data();
+}
- SHELLEXECUTEINFOW info;
- ZeroMemory(&info, sizeof(info));
- info.cbSize = sizeof(info);
- info.lpVerb = L"runas";
- info.lpFile = exe_path.c_str();
- const auto args = cmd_line.join_args();
- if (!args.empty())
- info.lpParameters = args.c_str();
- info.hwnd = hwnd;
- info.nShow = nShow;
+void runas(const CommandLine& cmd_line, HWND hwnd, int nShow) {
+ const auto exe_path = cmd_line.has_argv0() ? cmd_line.get_argv0() : get_executable_path();
- if (!ShellExecuteExW(&info))
- error::raise("ShellExecuteExW");
- }
+ SHELLEXECUTEINFOW info;
+ ZeroMemory(&info, sizeof(info));
+ info.cbSize = sizeof(info);
+ info.lpVerb = L"runas";
+ info.lpFile = exe_path.c_str();
+ const auto args = cmd_line.join_args();
+ if (!args.empty())
+ info.lpParameters = args.c_str();
+ info.hwnd = hwnd;
+ info.nShow = nShow;
- void runas_self(
- HWND hwnd,
- int nShow)
- {
- runas(CommandLine::query(), hwnd, nShow);
- }
+ if (!ShellExecuteExW(&info))
+ error::raise("ShellExecuteExW");
}
+
+void runas_self(HWND hwnd, int nShow) {
+ runas(CommandLine::query(), hwnd, nShow);
+}
+
+} // namespace process
diff --git a/src/process.hpp b/src/process.hpp
index c27dc3e..9ad93d9 100644
--- a/src/process.hpp
+++ b/src/process.hpp
@@ -5,36 +5,30 @@
#pragma once
-#include "error.hpp"
#include "cmd_line.hpp"
+#include "error.hpp"
#include <windows.h>
#include <string>
-namespace process
-{
- inline HMODULE load_exe_module()
- {
- const auto module = GetModuleHandle(NULL);
- if (module == NULL)
- error::raise("GetModuleHandle");
- return module;
- }
+namespace process {
- std::wstring get_executable_path();
-
- inline std::wstring get_command_line()
- {
- return GetCommandLine();
- }
+inline HMODULE load_exe_module() {
+ const auto module = GetModuleHandle(NULL);
+ if (module == NULL)
+ error::raise("GetModuleHandle");
+ return module;
+}
- void runas(
- const CommandLine& cmd_line,
- HWND hwnd = NULL,
- int nShow = SW_NORMAL);
+std::wstring get_executable_path();
- void runas_self(
- HWND hwnd = NULL,
- int nShow = SW_NORMAL);
+inline std::wstring get_command_line() {
+ return GetCommandLine();
}
+
+void runas(const CommandLine& cmd_line, HWND hwnd = NULL, int nShow = SW_NORMAL);
+
+void runas_self(HWND hwnd = NULL, int nShow = SW_NORMAL);
+
+} // namespace process
diff --git a/src/resource.hpp b/src/resource.hpp
index 6039fab..1f7b9ad 100644
--- a/src/resource.hpp
+++ b/src/resource.hpp
@@ -11,24 +11,19 @@
#include <windows.h>
#include <cstddef>
-
#include <string>
-namespace resource
-{
- inline std::wstring load_string(unsigned int id)
- {
- wchar_t* s = nullptr;
+namespace resource {
+
+inline std::wstring load_string(unsigned int id) {
+ wchar_t* s = nullptr;
- const auto ret = LoadStringW(
- process::load_exe_module(),
- id,
- reinterpret_cast<wchar_t*>(&s),
- 0);
+ const auto ret = LoadStringW(process::load_exe_module(), id, reinterpret_cast<wchar_t*>(&s), 0);
- if (ret <= 0)
- error::raise("LoadStringW");
+ if (ret <= 0)
+ error::raise("LoadStringW");
- return {s, static_cast<std::size_t>(ret)};
- }
+ return {s, static_cast<std::size_t>(ret)};
}
+
+} // namespace resource
diff --git a/src/sid.cpp b/src/sid.cpp
index 7a0e252..1a69763 100644
--- a/src/sid.cpp
+++ b/src/sid.cpp
@@ -3,69 +3,69 @@
// For details, see https://github.com/egor-tensin/privilege-check.
// Distributed under the MIT License.
-#include "error.hpp"
#include "sid.hpp"
+#include "error.hpp"
+
+/* clang-format off */
#include <windows.h>
#include <sddl.h>
+/* clang-format on */
#include <memory>
#include <string>
-namespace sid
-{
- SidBuffer well_known(WELL_KNOWN_SID_TYPE type)
- {
- SidBuffer buffer;
- DWORD cb = static_cast<DWORD>(buffer.size());
+namespace sid {
- if (!CreateWellKnownSid(type, NULL, buffer.data(), &cb))
- error::raise("CreateWellKnownSid");
+SidBuffer well_known(WELL_KNOWN_SID_TYPE type) {
+ SidBuffer buffer;
+ DWORD cb = static_cast<DWORD>(buffer.size());
- return buffer;
- }
+ if (!CreateWellKnownSid(type, NULL, buffer.data(), &cb))
+ error::raise("CreateWellKnownSid");
+
+ return buffer;
+}
+
+SidBuffer builtin_administrators() {
+ /*
+ void* sid = nullptr;
+ SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY;
- SidBuffer builtin_administrators()
+ if (!AllocateAndInitializeSid(
+ &authority,
+ 2,
+ SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS,
+ 0, 0, 0, 0, 0, 0,
+ &sid))
{
- /*
- void* sid = nullptr;
- SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY;
+ error::raise("AllocateAndInitializeSid");
+ }
- if (!AllocateAndInitializeSid(
- &authority,
- 2,
- SECURITY_BUILTIN_DOMAIN_RID,
- DOMAIN_ALIAS_RID_ADMINS,
- 0, 0, 0, 0, 0, 0,
- &sid))
- {
- error::raise("AllocateAndInitializeSid");
- }
+ return std::unique_ptr<void, FreeSid>{sid};
+ */
- return std::unique_ptr<void, FreeSid>{sid};
- */
+ return well_known(WinBuiltinAdministratorsSid);
+}
- return well_known(WinBuiltinAdministratorsSid);
- }
+namespace {
- namespace
- {
- struct LocalDelete
- {
- void operator()(wchar_t* s) const
- {
- LocalFree(s);
- }
- };
+struct LocalDelete {
+ void operator()(wchar_t* s) const {
+ LocalFree(s);
}
+};
- std::wstring to_string(const SidBuffer& sid)
- {
- wchar_t* s = nullptr;
+} // namespace
- if (!ConvertSidToStringSidW(const_cast<unsigned char*>(sid.data()), &s))
- error::raise("ConvertSidToStringSidW");
+std::wstring to_string(const SidBuffer& sid) {
+ wchar_t* s = nullptr;
- return std::unique_ptr<wchar_t, LocalDelete>{s}.get();
- }
+ if (!ConvertSidToStringSidW(const_cast<unsigned char*>(sid.data()), &s))
+ error::raise("ConvertSidToStringSidW");
+
+ return std::unique_ptr<wchar_t, LocalDelete>{s}.get();
}
+
+} // namespace sid
diff --git a/src/sid.hpp b/src/sid.hpp
index 2dc6111..a890e48 100644
--- a/src/sid.hpp
+++ b/src/sid.hpp
@@ -5,8 +5,10 @@
#pragma once
+/* clang-format off */
#include <windows.h>
#include <sddl.h>
+/* clang-format on */
#include <array>
#include <string>
@@ -15,11 +17,12 @@ constexpr DWORD max_sid_size = SECURITY_MAX_SID_SIZE;
typedef std::array<unsigned char, max_sid_size> SidBuffer;
-namespace sid
-{
- SidBuffer well_known(WELL_KNOWN_SID_TYPE type);
+namespace sid {
- SidBuffer builtin_administrators();
+SidBuffer well_known(WELL_KNOWN_SID_TYPE type);
- std::wstring to_string(const SidBuffer&);
-}
+SidBuffer builtin_administrators();
+
+std::wstring to_string(const SidBuffer&);
+
+} // namespace sid
diff --git a/src/string.hpp b/src/string.hpp
index 24d0425..dee1966 100644
--- a/src/string.hpp
+++ b/src/string.hpp
@@ -5,155 +5,136 @@
#pragma once
+#include <algorithm>
#include <cctype>
#include <cstddef>
-
-#include <algorithm>
#include <locale>
#include <sstream>
#include <string>
#include <type_traits>
#include <vector>
-namespace string
-{
- template <typename Char>
- void ltrim(std::basic_string<Char>& s)
- {
- s.erase(s.begin(), std::find_if(s.begin(), s.end(), [] (const Char& c)
- {
- return !std::isspace(c);
- }));
- }
-
- template <typename Char>
- void rtrim(std::basic_string<Char>& s)
- {
- s.erase(std::find_if(s.rbegin(), s.rend(), [] (const Char& c)
- {
- return !std::isspace(c);
- }).base(), s.end());
- }
+namespace string {
- template <typename Char>
- void trim(std::basic_string<Char>& s)
- {
- ltrim(s);
- rtrim(s);
- }
+template <typename Char>
+void ltrim(std::basic_string<Char>& s) {
+ s.erase(s.begin(),
+ std::find_if(s.begin(), s.end(), [](const Char& c) { return !std::isspace(c); }));
+}
- template <typename Char, typename Sep, typename InputIterator>
- std::basic_string<Char> join(
- const Sep& sep,
- InputIterator beg,
- InputIterator end)
- {
- std::basic_ostringstream<Char> oss;
+template <typename Char>
+void rtrim(std::basic_string<Char>& s) {
+ s.erase(
+ std::find_if(s.rbegin(), s.rend(), [](const Char& c) { return !std::isspace(c); }).base(),
+ s.end());
+}
- if (beg != end)
- {
- oss << *beg;
- ++beg;
- }
+template <typename Char>
+void trim(std::basic_string<Char>& s) {
+ ltrim(s);
+ rtrim(s);
+}
- for (; beg != end; ++beg)
- oss << sep << *beg;
+template <typename Char, typename Sep, typename InputIterator>
+std::basic_string<Char> join(const Sep& sep, InputIterator beg, InputIterator end) {
+ std::basic_ostringstream<Char> oss;
- return oss.str();
+ if (beg != end) {
+ oss << *beg;
+ ++beg;
}
- template <typename Char, typename Sep>
- std::basic_string<Char> join(
- const Sep& sep,
- const std::vector<std::basic_string<Char>>& args)
- {
- return join<Char>(sep, args.cbegin(), args.cend());
- }
+ for (; beg != end; ++beg)
+ oss << sep << *beg;
- template <typename Char, typename String, typename = void>
- struct StringHelper
- { };
+ return oss.str();
+}
- template <typename Char, typename String>
- struct StringHelper<Char, String, typename std::enable_if<std::is_same<typename std::decay<typename std::remove_pointer<String>::type>::type, Char>::value>::type>
- {
- StringHelper(const Char& c)
- : buf{&c}
- , len{1}
- { }
+template <typename Char, typename Sep>
+std::basic_string<Char> join(const Sep& sep, const std::vector<std::basic_string<Char>>& args) {
+ return join<Char>(sep, args.cbegin(), args.cend());
+}
- StringHelper(const Char* s)
- : buf{s}
- , len{std::char_traits<Char>::length(s)}
- { }
+template <typename Char, typename String, typename = void>
+struct StringHelper {};
- const Char* buffer() const { return buf; }
+template <typename Char, typename String>
+struct StringHelper<Char,
+ String,
+ typename std::enable_if<std::is_same<
+ typename std::decay<typename std::remove_pointer<String>::type>::type,
+ Char>::value>::type> {
+ StringHelper(const Char& c) : buf{&c}, len{1} {}
- std::size_t length() const { return len; }
+ StringHelper(const Char* s) : buf{s}, len{std::char_traits<Char>::length(s)} {}
- private:
- const Char* const buf;
- const std::size_t len;
- };
+ const Char* buffer() const {
+ return buf;
+ }
- template <typename Char, typename String>
- struct StringHelper<Char, String, typename std::enable_if<std::is_same<String, std::basic_string<Char>>::value>::type>
- {
- StringHelper(const std::basic_string<Char>& s)
- : s{s}
- { }
+ std::size_t length() const {
+ return len;
+ }
- const Char* buffer() const { return s.c_str(); }
+private:
+ const Char* const buf;
+ const std::size_t len;
+};
- std::size_t length() const { return s.length(); }
+template <typename Char, typename String>
+struct StringHelper<
+ Char,
+ String,
+ typename std::enable_if<std::is_same<String, std::basic_string<Char>>::value>::type> {
+ StringHelper(const std::basic_string<Char>& s) : s{s} {}
- private:
- const std::basic_string<Char>& s;
- };
+ const Char* buffer() const {
+ return s.c_str();
+ }
- template <typename Char, typename What, typename By>
- void replace(
- std::basic_string<Char>& s,
- const What& what,
- const By& by)
- {
- std::size_t pos = 0;
+ std::size_t length() const {
+ return s.length();
+ }
- const StringHelper<Char, typename std::decay<What>::type> what_helper{what};
- const StringHelper<Char, typename std::decay<By>::type> by_helper{by};
+private:
+ const std::basic_string<Char>& s;
+};
- const auto what_buf = what_helper.buffer();
- const auto what_len = what_helper.length();
+template <typename Char, typename What, typename By>
+void replace(std::basic_string<Char>& s, const What& what, const By& by) {
+ std::size_t pos = 0;
- const auto by_buf = by_helper.buffer();
- const auto by_len = by_helper.length();
+ const StringHelper<Char, typename std::decay<What>::type> what_helper{what};
+ const StringHelper<Char, typename std::decay<By>::type> by_helper{by};
- while ((pos = s.find(what_buf, pos, what_len)) != std::basic_string<Char>::npos)
- {
- s.replace(pos, what_len, by_buf, by_len);
- pos += by_len;
- }
+ const auto what_buf = what_helper.buffer();
+ const auto what_len = what_helper.length();
+
+ const auto by_buf = by_helper.buffer();
+ const auto by_len = by_helper.length();
+
+ while ((pos = s.find(what_buf, pos, what_len)) != std::basic_string<Char>::npos) {
+ s.replace(pos, what_len, by_buf, by_len);
+ pos += by_len;
}
+}
- template <typename Char, typename What>
- void prefix_with(
- std::basic_string<Char>& s,
- const What& what,
- const Char& by)
- {
- const StringHelper<Char, typename std::decay<What>::type> what_helper{what};
+template <typename Char, typename What>
+void prefix_with(std::basic_string<Char>& s, const What& what, const Char& by) {
+ const StringHelper<Char, typename std::decay<What>::type> what_helper{what};
- const auto what_buf = what_helper.buffer();
- const auto what_len = what_helper.length();
+ const auto what_buf = what_helper.buffer();
+ const auto what_len = what_helper.length();
- std::size_t numof_by = 0;
+ std::size_t numof_by = 0;
- for (std::size_t i = 0; i < what_len; ++i)
- numof_by += std::count(s.cbegin(), s.cend(), what_buf[i]);
+ for (std::size_t i = 0; i < what_len; ++i)
+ numof_by += std::count(s.cbegin(), s.cend(), what_buf[i]);
- s.reserve(s.capacity() + numof_by);
+ s.reserve(s.capacity() + numof_by);
- for (std::size_t i = 0; i < what_len; ++i)
- replace(s, what_buf[i], by);
- }
+ for (std::size_t i = 0; i < what_len; ++i)
+ replace(s, what_buf[i], by);
}
+
+} // namespace string
diff --git a/src/token.cpp b/src/token.cpp
index f7ad38e..1333290 100644
--- a/src/token.cpp
+++ b/src/token.cpp
@@ -3,6 +3,8 @@
// For details, see https://github.com/egor-tensin/privilege-check.
// Distributed under the MIT License.
+#include "token.hpp"
+
#include "error.hpp"
#include "handle.hpp"
#include "os.hpp"
@@ -15,153 +17,140 @@
#include <utility>
#include <vector>
-namespace token
-{
- Handle open_for_process(
- const Handle& process,
- DWORD permissions)
- {
- HANDLE raw;
+namespace token {
- if (!OpenProcessToken(process, permissions, &raw))
- error::raise("OpenProcessToken");
+Handle open_for_process(const Handle& process, DWORD permissions) {
+ HANDLE raw;
- return Handle{raw};
- }
+ if (!OpenProcessToken(process, permissions, &raw))
+ error::raise("OpenProcessToken");
- Handle open_for_current_process(
- DWORD permissions)
- {
- return open_for_process(Handle{GetCurrentProcess()}, permissions);
- }
+ return Handle{raw};
+}
+
+Handle open_for_current_process(DWORD permissions) {
+ return open_for_process(Handle{GetCurrentProcess()}, permissions);
+}
- bool get_linked(Handle& token)
- {
- if (!os::is_vista_or_later())
- return false;
+bool get_linked(Handle& token) {
+ if (!os::is_vista_or_later())
+ return false;
- auto type = TokenElevationTypeDefault;
- DWORD cb = 0;
+ auto type = TokenElevationTypeDefault;
+ DWORD cb = 0;
- if (!GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &cb))
- error::raise("GetTokenInformation");
+ if (!GetTokenInformation(token, TokenElevationType, &type, sizeof(type), &cb))
+ error::raise("GetTokenInformation");
- if (type != TokenElevationTypeLimited)
- return false;
+ if (type != TokenElevationTypeLimited)
+ return false;
- HANDLE raw;
+ HANDLE raw;
- if (!GetTokenInformation(token, TokenLinkedToken, &raw, sizeof(raw), &cb))
- error::raise("GetTokenInformation");
+ if (!GetTokenInformation(token, TokenLinkedToken, &raw, sizeof(raw), &cb))
+ error::raise("GetTokenInformation");
- token = Handle{raw};
- return true;
- }
+ token = Handle{raw};
+ return true;
+}
- Handle get_for_identification(const Handle& token)
- {
- HANDLE raw;
+Handle get_for_identification(const Handle& token) {
+ HANDLE raw;
- if (!DuplicateToken(token, SecurityIdentification, &raw))
- error::raise("DuplicateToken");
+ if (!DuplicateToken(token, SecurityIdentification, &raw))
+ error::raise("DuplicateToken");
- return Handle{raw};
- }
+ return Handle{raw};
+}
- //
- // FUNCTION: query_integrity_level()
- //
- // RETURN VALUE: Returns the integrity level of the current process. It is
- // usually one of these values:
- //
- // SECURITY_MANDATORY_UNTRUSTED_RID (SID: S-1-16-0x0)
- // Means untrusted level. It is used by processes started by the
- // Anonymous group. Blocks most write access.
- //
- // SECURITY_MANDATORY_LOW_RID (SID: S-1-16-0x1000)
- // Means low integrity level. It is used by Protected Mode Internet
- // Explorer. Blocks write acess to most objects (such as files and
- // registry keys) on the system.
- //
- // SECURITY_MANDATORY_MEDIUM_RID (SID: S-1-16-0x2000)
- // Means medium integrity level. It is used by normal applications
- // being launched while UAC is enabled.
- //
- // SECURITY_MANDATORY_HIGH_RID (SID: S-1-16-0x3000)
- // Means high integrity level. It is used by administrative applications
- // launched through elevation when UAC is enabled, or normal
- // applications if UAC is disabled and the user is an administrator.
- //
- // SECURITY_MANDATORY_SYSTEM_RID (SID: S-1-16-0x4000)
- // Means system integrity level. It is used by services and other
- // system-level applications (such as Wininit, Winlogon, Smss, etc.)
- //
- DWORD query_integrity_level(const Handle& token)
- {
- DWORD cb = 0;
+//
+// FUNCTION: query_integrity_level()
+//
+// RETURN VALUE: Returns the integrity level of the current process. It is
+// usually one of these values:
+//
+// SECURITY_MANDATORY_UNTRUSTED_RID (SID: S-1-16-0x0)
+// Means untrusted level. It is used by processes started by the
+// Anonymous group. Blocks most write access.
+//
+// SECURITY_MANDATORY_LOW_RID (SID: S-1-16-0x1000)
+// Means low integrity level. It is used by Protected Mode Internet
+// Explorer. Blocks write acess to most objects (such as files and
+// registry keys) on the system.
+//
+// SECURITY_MANDATORY_MEDIUM_RID (SID: S-1-16-0x2000)
+// Means medium integrity level. It is used by normal applications
+// being launched while UAC is enabled.
+//
+// SECURITY_MANDATORY_HIGH_RID (SID: S-1-16-0x3000)
+// Means high integrity level. It is used by administrative applications
+// launched through elevation when UAC is enabled, or normal
+// applications if UAC is disabled and the user is an administrator.
+//
+// SECURITY_MANDATORY_SYSTEM_RID (SID: S-1-16-0x4000)
+// Means system integrity level. It is used by services and other
+// system-level applications (such as Wininit, Winlogon, Smss, etc.)
+//
+DWORD query_integrity_level(const Handle& token) {
+ DWORD cb = 0;
- if (!GetTokenInformation(token, TokenIntegrityLevel, NULL, 0, &cb))
- {
- switch (GetLastError())
- {
- case ERROR_INSUFFICIENT_BUFFER:
- break;
- default:
- error::raise("GetTokenInformation");
- }
+ if (!GetTokenInformation(token, TokenIntegrityLevel, NULL, 0, &cb)) {
+ switch (GetLastError()) {
+ case ERROR_INSUFFICIENT_BUFFER:
+ break;
+ default:
+ error::raise("GetTokenInformation");
}
+ }
- std::vector<unsigned char> buf(cb);
- const auto token_level = reinterpret_cast<TOKEN_MANDATORY_LABEL*>(buf.data());
+ std::vector<unsigned char> buf(cb);
+ const auto token_level = reinterpret_cast<TOKEN_MANDATORY_LABEL*>(buf.data());
- if (!GetTokenInformation(token, TokenIntegrityLevel, token_level, cb, &cb))
- error::raise("GetTokenInformation");
+ if (!GetTokenInformation(token, TokenIntegrityLevel, token_level, cb, &cb))
+ error::raise("GetTokenInformation");
- // Integrity Level SIDs are in the form of S-1-16-0xXXXX. (e.g.
- // S-1-16-0x1000 stands for low integrity level SID). There is one and
- // only one subauthority.
- return *GetSidSubAuthority(token_level->Label.Sid, 0);
- }
+ // Integrity Level SIDs are in the form of S-1-16-0xXXXX. (e.g.
+ // S-1-16-0x1000 stands for low integrity level SID). There is one and
+ // only one subauthority.
+ return *GetSidSubAuthority(token_level->Label.Sid, 0);
+}
- std::wstring integrity_level_to_string(DWORD level)
- {
- static const std::unordered_map<DWORD, const wchar_t*> names =
- {
- {SECURITY_MANDATORY_UNTRUSTED_RID, L"Untrusted"},
- {SECURITY_MANDATORY_LOW_RID, L"Low"},
- {SECURITY_MANDATORY_MEDIUM_RID, L"Medium"},
- {SECURITY_MANDATORY_HIGH_RID, L"High"},
- {SECURITY_MANDATORY_SYSTEM_RID, L"System"},
- };
+std::wstring integrity_level_to_string(DWORD level) {
+ static const std::unordered_map<DWORD, const wchar_t*> names = {
+ {SECURITY_MANDATORY_UNTRUSTED_RID, L"Untrusted"},
+ {SECURITY_MANDATORY_LOW_RID, L"Low"},
+ {SECURITY_MANDATORY_MEDIUM_RID, L"Medium"},
+ {SECURITY_MANDATORY_HIGH_RID, L"High"},
+ {SECURITY_MANDATORY_SYSTEM_RID, L"System"},
+ };
- static constexpr auto unknown_name = L"Unknown";
+ static constexpr auto unknown_name = L"Unknown";
- const auto it = names.find(level);
+ const auto it = names.find(level);
- if (it == names.cend())
- return unknown_name;
+ if (it == names.cend())
+ return unknown_name;
- return it->second;
- }
+ return it->second;
+}
- bool check_belongs(const Handle& token, const SidBuffer& sid)
- {
- BOOL b = FALSE;
+bool check_belongs(const Handle& token, const SidBuffer& sid) {
+ BOOL b = FALSE;
- if (!CheckTokenMembership(token, const_cast<unsigned char*>(sid.data()), &b))
- error::raise("CheckTokenMembership");
+ if (!CheckTokenMembership(token, const_cast<unsigned char*>(sid.data()), &b))
+ error::raise("CheckTokenMembership");
- return b != FALSE;
- }
+ return b != FALSE;
+}
- bool query_elevation(const Handle& token)
- {
- TOKEN_ELEVATION elevation;
- DWORD cb = 0;
+bool query_elevation(const Handle& token) {
+ TOKEN_ELEVATION elevation;
+ DWORD cb = 0;
- if (!GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &cb))
- error::raise("GetTokenInformation");
+ if (!GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &cb))
+ error::raise("GetTokenInformation");
- return elevation.TokenIsElevated != 0;
- }
+ return elevation.TokenIsElevated != 0;
}
+
+} // namespace token
diff --git a/src/token.hpp b/src/token.hpp
index 5ad32bf..2ccee13 100644
--- a/src/token.hpp
+++ b/src/token.hpp
@@ -12,36 +12,40 @@
#include <string>
-namespace token
-{
- namespace permissions
- {
- constexpr DWORD query() { return TOKEN_QUERY; }
+namespace token {
+namespace permissions {
- constexpr DWORD duplicate() { return TOKEN_DUPLICATE; }
- }
+constexpr DWORD query() {
+ return TOKEN_QUERY;
+}
- constexpr DWORD default_permissions = permissions::query();
+constexpr DWORD duplicate() {
+ return TOKEN_DUPLICATE;
+}
- // Current thread's primary impersonation token.
- inline Handle dumb() { return Handle{NULL}; }
+} // namespace permissions
- Handle open_for_process(
- const Handle& process,
- DWORD permissions = default_permissions);
+constexpr DWORD default_permissions = permissions::query();
- Handle open_for_current_process(
- DWORD permissions = default_permissions);
+// Current thread's primary impersonation token.
+inline Handle dumb() {
+ return Handle{NULL};
+}
- bool get_linked(Handle& token);
+Handle open_for_process(const Handle& process, DWORD permissions = default_permissions);
- Handle get_for_identification(const Handle& token);
+Handle open_for_current_process(DWORD permissions = default_permissions);
- DWORD query_integrity_level(const Handle& token);
+bool get_linked(Handle& token);
- std::wstring integrity_level_to_string(DWORD);
+Handle get_for_identification(const Handle& token);
- bool check_belongs(const Handle& token, const SidBuffer& sid);
+DWORD query_integrity_level(const Handle& token);
- bool query_elevation(const Handle& token);
-}
+std::wstring integrity_level_to_string(DWORD);
+
+bool check_belongs(const Handle& token, const SidBuffer& sid);
+
+bool query_elevation(const Handle& token);
+
+} // namespace token