Skip to content

Commit

Permalink
Merge pull request #10 from ITachiLab/feature/#9-detect-admin
Browse files Browse the repository at this point in the history
[GH-9] Warning message when running Hotkey Detective as a non-admin
  • Loading branch information
ITachiLab authored Aug 25, 2021
2 parents 0b74f1e + e878355 commit 3ac9f59
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 6 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,16 @@ add_subdirectory(dll)

set(CMAKE_CXX_STANDARD 17)

# This option will terminate all strings in the resources with proper null
# characters.
set(CMAKE_RC_FLAGS "/n")

add_definitions(-DUNICODE)

add_executable(HotkeyDetective WIN32
src/MainWindow.cpp
src/HotkeyTable.cpp
src/WindowsUtils.cpp
src/Core.cpp
src/main.cpp
res/resources.rc)
Expand Down
6 changes: 6 additions & 0 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ system.

== Changelog

=== 1.1.0

Added a warning message when trying to run Hotkey Detective as a non-admin user.
This will greatly improve user experience, especially among users not reading
readmes (I'm not reading them too, though).

=== 1.0.0

The first major that brings up a basic but friendly UI in place of the scary
Expand Down
30 changes: 30 additions & 0 deletions include/WindowsUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef HOTKEY_DETECTIVE_INCLUDE_WINDOWSUTILS_H_
#define HOTKEY_DETECTIVE_INCLUDE_WINDOWSUTILS_H_

#include <windows.h>

namespace WindowsUtils {
/*!
* \brief Check if the running user has administrator privileges.
*
* @return If the running user has administrator privileges, the function
* returns true. Otherwise, when the user doesn't belong to the "Administrators"
* group, or there are errors while checking the affiliation, the result is
* false.
*/
BOOL isUserAdmin();

/*!
* \brief Return a read-only pointer to a string resource.
*
* This function can be used to retrieve a read-only pointer to any string
* resource defined in this application.
*
* @param[in] strResource an ID of the string resource
* @return If the function succeeds, the return value is a read-only pointer to
* the desired string resource. Otherwise, the return value is a nullptr.
*/
const wchar_t *resStr(int strResource);
}

#endif //HOTKEY_DETECTIVE_INCLUDE_WINDOWSUTILS_H_
7 changes: 5 additions & 2 deletions res/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
#define IDC_STATIC (-1)
#endif

#define ID_TABLE 101
#define ID_TABLE_HOTKEYS 101

#define IDI_MAIN_ICON 200
#define ID_ICON_MAIN 200

#define ID_STRING_APP_NAME 300
#define ID_STRING_ADMIN_WARNING 301
8 changes: 7 additions & 1 deletion res/resources.rc
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
#include "resource.h"

IDI_MAIN_ICON ICON "main.ico"
ID_ICON_MAIN ICON "main.ico"

STRINGTABLE
BEGIN
ID_STRING_APP_NAME "Hotkey Detective"
ID_STRING_ADMIN_WARNING "You are trying to run Hotkey Detective without administrator privileges. If you proceed, Hotkey Detective won't be able to detect all hotkeys. Are you sure you want to continue?"
END
2 changes: 1 addition & 1 deletion src/HotkeyTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void HotkeyTable::addToWindow(HWND parentWindow, HINSTANCE hInstance) {
rcClient.right - rcClient.left,
rcClient.bottom - rcClient.top,
parentWindow,
(HMENU) ID_TABLE,
(HMENU) ID_TABLE_HOTKEYS,
hInstance,
NULL);

Expand Down
2 changes: 1 addition & 1 deletion src/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ MainWindow::MainWindow(const HINSTANCE hInstance)

RegisterClassW(&wc);

mainIcon = LoadIconW(hInstance, MAKEINTRESOURCE(IDI_MAIN_ICON));
mainIcon = LoadIconW(hInstance, MAKEINTRESOURCE(ID_ICON_MAIN));
}

LRESULT MainWindow::windowProc(HWND hwnd, UINT uMsg, WPARAM wParam,
Expand Down
35 changes: 35 additions & 0 deletions src/WindowsUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "WindowsUtils.h"

#include <securitybaseapi.h>

BOOL WindowsUtils::isUserAdmin() {
SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY;
PSID administratorsGroup;

BOOL result = AllocateAndInitializeSid(&authority, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&administratorsGroup);

if (result) {
// If this call fails, that means an error, so we can as well assume
// the user has no admin rights.
if (!CheckTokenMembership(nullptr, administratorsGroup, &result)) {
result = FALSE;
}

FreeSid(administratorsGroup);
}

return result;
}

const wchar_t *WindowsUtils::resStr(int strResource) {
HINSTANCE hInstance = GetModuleHandleW(nullptr);

const wchar_t* strPtr = nullptr;
LoadStringW(hInstance, strResource, (LPWSTR) &strPtr, 0);

return strPtr;
}
15 changes: 14 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,28 @@

#include <HotkeyTable.h>
#include <MainWindow.h>
#include <WindowsUtils.h>
#include <resource.h>

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PWSTR cmdLine, int cmdShow) {

if (!WindowsUtils::isUserAdmin()) {
int userSelection = MessageBoxW(
nullptr, WindowsUtils::resStr(ID_STRING_ADMIN_WARNING),
WindowsUtils::resStr(ID_STRING_APP_NAME),
MB_YESNO | MB_ICONWARNING);

if (userSelection == IDNO) {
return 0;
}
}

MainWindow *window = MainWindow::GetInstance(hInstance);

ShowWindow(window->getHandle(), cmdShow);

MSG msg = { };
MSG msg = {};

while (GetMessageW(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
Expand Down

0 comments on commit 3ac9f59

Please sign in to comment.