11#include " pch.h"
22#include " HutaoNativeRegistryNotification.h"
33#include " HutaoNativeRegistryNotificationCallBack.h"
4+ #include < algorithm>
45
5- HutaoNativeRegistryNotification::HutaoNativeRegistryNotification ()
6+ HutaoNativeRegistryNotification::HutaoNativeRegistryNotification (HutaoString keyPath )
67 : callback_(0 )
78 , userData_(0 )
89 , hKey_(nullptr )
10+ , keyPath_(keyPath)
911{
1012}
1113
@@ -37,16 +39,73 @@ DWORD WINAPI HutaoNativeRegistryNotification::NotificationThreadProc(LPVOID lpPa
3739 return 0 ;
3840}
3941
42+ bool HutaoNativeRegistryNotification::ParseRegistryPath (const HutaoString& path, HKEY& outRootKey, HutaoString& outSubKey)
43+ {
44+ outRootKey = nullptr ;
45+ outSubKey = HutaoString ();
46+
47+ // Trim and normalize case using HutaoString methods
48+ HutaoString trimmed = path.Trim ();
49+ if (trimmed.IsEmpty ())
50+ {
51+ return false ;
52+ }
53+
54+ // Find separator
55+ int idx = trimmed.IndexOf (L' \\ ' );
56+ HutaoString hiveName;
57+ if (idx < 0 )
58+ {
59+ hiveName = trimmed;
60+ outSubKey = HutaoString ();
61+ }
62+ else
63+ {
64+ hiveName = trimmed.Substring (0 , static_cast <size_t >(idx));
65+ outSubKey = trimmed.Substring (static_cast <size_t >(idx + 1 ));
66+ }
67+
68+ HutaoString hiveUpper = hiveName.ToUpper ();
69+
70+ if (hiveUpper == L" HKEY_CLASSES_ROOT" || hiveUpper == L" HKCR" )
71+ {
72+ outRootKey = HKEY_CLASSES_ROOT;
73+ }
74+ else if (hiveUpper == L" HKEY_CURRENT_USER" || hiveUpper == L" HKCU" )
75+ {
76+ outRootKey = HKEY_CURRENT_USER;
77+ }
78+ else if (hiveUpper == L" HKEY_LOCAL_MACHINE" || hiveUpper == L" HKLM" )
79+ {
80+ outRootKey = HKEY_LOCAL_MACHINE;
81+ }
82+ else if (hiveUpper == L" HKEY_USERS" || hiveUpper == L" HKU" )
83+ {
84+ outRootKey = HKEY_USERS;
85+ }
86+ else if (hiveUpper == L" HKEY_CURRENT_CONFIG" || hiveUpper == L" HKCC" )
87+ {
88+ outRootKey = HKEY_CURRENT_CONFIG;
89+ }
90+ else
91+ {
92+ return false ;
93+ }
94+
95+ return true ;
96+ }
97+
4098void HutaoNativeRegistryNotification::NotificationThread ()
4199{
42- // Parse registry path from C# code: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections
43- // We need to open HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings
44- // and watch for changes in the Connections subkey
45-
46- HKEY hRootKey = HKEY_CURRENT_USER;
47- HutaoString subKey = L" Software\\ Microsoft\\ Windows\\ CurrentVersion\\ Internet Settings" ;
48-
49- LONG result = RegOpenKeyExW (hRootKey, subKey.Data (), 0 , KEY_NOTIFY | KEY_READ, &hKey_);
100+ HKEY root = HKEY_CURRENT_USER;
101+ HutaoString subKey;
102+ if (!ParseRegistryPath (keyPath_, root, subKey))
103+ {
104+ return ;
105+ }
106+
107+ // Open the target key (subKey may be empty meaning the root hive)
108+ LONG result = RegOpenKeyExW (root, subKey.IsEmpty () ? nullptr : subKey.Data (), 0 , KEY_NOTIFY | KEY_READ, &hKey_);
50109 if (result != ERROR_SUCCESS)
51110 {
52111 // Failed to open registry key
@@ -64,10 +123,7 @@ void HutaoNativeRegistryNotification::NotificationThread()
64123
65124 while (!stopRequested_)
66125 {
67- // Watch for changes in the Connections subkey
68- // We use REG_NOTIFY_CHANGE_LAST_SET to detect value changes
69- // and REG_NOTIFY_CHANGE_NAME to detect subkey changes
70- // Set bWatchSubtree to TRUE to monitor the Connections subkey as well
126+ // Watch for changes in the key and its subkeys
71127 result = RegNotifyChangeKeyValue (
72128 hKey_, // hKey
73129 TRUE , // bWatchSubtree (TRUE = this key and all subkeys)
@@ -90,7 +146,7 @@ void HutaoNativeRegistryNotification::NotificationThread()
90146 // Registry changed, call the callback
91147 if (callback_.has_value ())
92148 {
93- callback_.value ()(userData_);
149+ callback_.value ()(userData_);
94150 }
95151 }
96152 else if (waitResult == WAIT_TIMEOUT)
0 commit comments