// Notify of a change in the specified registry key/hive bool RegKey::NotifyChange(LPCTSTR pszKeyName, DWORD dwNotifyfilter, bool bWatchSubKeys /* = false */, HANDLE hEvent /* = NULL */, HKEY hBaseKey /* = HKEY_CURRENT_USER */) { if (pszKeyName == NULL) { iLastErrorCode_ = ERROR_BAD_ARGUMENTS; return false; } if (!OpenKey(pszKeyName, false, hBaseKey, NULL)) return false; LONG lRetValue = ERROR_SUCCESS; if (hEvent == NULL) lRetValue = RegNotifyChangeKeyValue(hTheKey_, bWatchSubKeys, dwNotifyfilter, hEvent, FALSE); else lRetValue = RegNotifyChangeKeyValue(hTheKey_, bWatchSubKeys, dwNotifyfilter, hEvent, TRUE); if (lRetValue == ERROR_CALL_NOT_IMPLEMENTED) // NT ONLY { iLastErrorCode_ = ERROR_CALL_NOT_IMPLEMENTED; return false; } if (lRetValue != ERROR_SUCCESS) { iLastErrorCode_ = GetLastError(); return false; } iLastErrorCode_ = ERROR_SUCCESS; return true; }
bool RegKey::StartWatching() { if(!watch_event_) { watch_event_ = CreateEvent(NULL, TRUE, FALSE, NULL); } DWORD filter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY; // Watch the registry key for a change of value. HRESULT result = RegNotifyChangeKeyValue(key_, TRUE, filter, watch_event_, TRUE); if(SUCCEEDED(result)) { return true; } else { CloseHandle(watch_event_); watch_event_ = 0; return false; } }
void RazerMonitorThread::Execute(void * data) { bool rereg = true; while(!isTerminated()) { if(rereg) { LONG lError = RegNotifyChangeKeyValue(hMonitoredKey, true, REG_NOTIFY_CHANGE_LAST_SET, hKeyEvent, true); if(lError != ERROR_SUCCESS) { ErrorMsg("RegNotifyChangeKeyValue"); setTerminated(true); } rereg = false; } DWORD ret = WaitForSingleObject(hKeyEvent, 1000); if(ret != WAIT_FAILED && ret != WAIT_TIMEOUT) { for(int i = 0; i < NUM_MONITORED_KEYS; i++) keyChangeCallbacks[i](); rereg = true; } else if(ret == WAIT_TIMEOUT) { addAPM(); } } if(hKeyEvent != NULL) CloseHandle(hKeyEvent); if(hMonitoredKey != NULL) RegCloseKey(hMonitoredKey); }
void CConnectionManager::RegistryWatchDogThread() { HKEY hKey; if (RegOpenKeyEx(HKEY_CURRENT_USER, REGISTRY_ROOT_KEY_SITES_PARENT, 0, KEY_NOTIFY, &hKey) != ERROR_SUCCESS) { TRACE_E(FS(_T("Registry watchdog thread unable to open registry key: %s"), REGISTRY_ROOT_KEY_SITES_PARENT)); _endthreadex(2); return; } while (true) { if (RegNotifyChangeKeyValue(hKey, TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_LAST_SET, NULL, FALSE)!=ERROR_SUCCESS) { TRACE_E(_T("Registry watchdog thread unable to setup next waiting operation")); _endthreadex(1); return; } TRACE_W(_T("Registry watchdog triggered")); m_CS.Enter(); m_SitesModel.Load(REGISTRY_ROOT_KEY_SITES); m_CS.Leave(); TRACE_W(_T("Sites model reloaded!")); } RegCloseKey(hKey); _endthread(); }
NS_IMETHODIMP nsWindowsRegKey::StartWatching(PRBool recurse) { #ifdef WINCE return NS_ERROR_NOT_IMPLEMENTED; #else NS_ENSURE_TRUE(mKey, NS_ERROR_NOT_INITIALIZED); if (mWatchEvent) return NS_OK; mWatchEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (!mWatchEvent) return NS_ERROR_OUT_OF_MEMORY; DWORD filter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY; LONG rv = RegNotifyChangeKeyValue(mKey, recurse, filter, mWatchEvent, TRUE); if (rv != ERROR_SUCCESS) { StopWatching(); // On older versions of Windows, this call is not implemented, so simply // return NS_OK in those cases and pretend that the watching is happening. return (rv == ERROR_CALL_NOT_IMPLEMENTED) ? NS_OK : NS_ERROR_FAILURE; } mWatchRecursive = recurse; return NS_OK; #endif }
NS_IMETHODIMP nsWindowsRegKey::StartWatching(bool aRecurse) { if (NS_WARN_IF(!mKey)) { return NS_ERROR_NOT_INITIALIZED; } if (mWatchEvent) { return NS_OK; } mWatchEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr); if (!mWatchEvent) { return NS_ERROR_OUT_OF_MEMORY; } DWORD filter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY; LONG rv = RegNotifyChangeKeyValue(mKey, aRecurse, filter, mWatchEvent, TRUE); if (rv != ERROR_SUCCESS) { StopWatching(); // On older versions of Windows, this call is not implemented, so simply // return NS_OK in those cases and pretend that the watching is happening. return (rv == ERROR_CALL_NOT_IMPLEMENTED) ? NS_OK : NS_ERROR_FAILURE; } mWatchRecursive = aRecurse; return NS_OK; }
unsigned WINAPI CConfigPropertySheet::WatchRegistry ( LPVOID inParam ) { bool done = false; CConfigPropertySheet * self = reinterpret_cast<CConfigPropertySheet*>(inParam); check( self ); while ( !done ) { RegNotifyChangeKeyValue( self->m_statusKey, TRUE, REG_NOTIFY_CHANGE_LAST_SET, NULL, FALSE ); EnterCriticalSection( &self->m_lock ); done = ( self->m_statusKey == NULL ) ? true : false; if ( !done ) { self->PostMessage( WM_REGISTRYCHANGED, 0, 0 ); } LeaveCriticalSection( &self->m_lock ); } SetEvent( self->m_threadExited ); return 0; }
bool ShellCache::RefreshIfNeeded() { // don't wait for the registry change event but only test if such an event // has occurred since the last time we got here. // if the event has occurred, re-read all registry variables and of course // re-set the notification event to get further notifications of registry changes. bool signalled = WaitForSingleObjectEx(m_registryChangeEvent, 0, true) != WAIT_TIMEOUT; if (!signalled) return signalled; if (RegNotifyChangeKeyValue(m_hNotifyRegKey, false, REG_NOTIFY_CHANGE_LAST_SET, m_registryChangeEvent, TRUE) != ERROR_SUCCESS) { CloseHandle(m_registryChangeEvent); m_registryChangeEvent = nullptr; RegCloseKey(m_hNotifyRegKey); m_hNotifyRegKey = nullptr; } cachetype.read(); showrecursive.read(); folderoverlay.read(); driveremote.read(); drivefixed.read(); drivecdrom.read(); driveremove.read(); drivefloppy.read(); driveram.read(); driveunknown.read(); simplecontext.read(); shellmenuaccelerators.read(); unversionedasmodified.read(); recursesubmodules.read(); showunversionedoverlay.read(); showignoredoverlay.read(); excludedasnormal.read(); hidemenusforunversioneditems.read(); menulayoutlow.read(); menulayouthigh.read(); langid.read(); blockstatus.read(); getlocktop.read(); menumasklow_lm.read(); menumaskhigh_lm.read(); menumasklow_cu.read(); menumaskhigh_cu.read(); nocontextpaths.read(); Locker lock(m_critSec); pathFilter.Refresh(); return signalled; }
BOOL My_RegNotifyChangeKeyValue() { HKEY hKey=NULL; BOOL bWatchSubtree=NULL; DWORD dwNotifyFilter=NULL; HANDLE hEvent=NULL; BOOL fAsynchronous=NULL; LONG returnVal_Real = NULL; LONG returnVal_Intercepted = NULL; DWORD error_Real = 0; DWORD error_Intercepted = 0; __try{ disableInterception(); returnVal_Real = RegNotifyChangeKeyValue (hKey,bWatchSubtree,dwNotifyFilter,hEvent,fAsynchronous); error_Real = GetLastError(); enableInterception(); returnVal_Intercepted = RegNotifyChangeKeyValue (hKey,bWatchSubtree,dwNotifyFilter,hEvent,fAsynchronous); error_Intercepted = GetLastError(); }__except(puts("in filter"), 1){puts("exception caught");} return ((returnVal_Real == returnVal_Intercepted) && (error_Real == error_Intercepted)); }
static inline int registerNotification(const HKEY& hKey, HANDLE& hEvent) { LONG lrc = RegNotifyChangeKeyValue(hKey, TRUE, REG_NOTIFY_CHANGE_LAST_SET, hEvent, TRUE); AssertMsgReturn(lrc == ERROR_SUCCESS, ("Failed to register event on the key. Please debug me!"), VERR_INTERNAL_ERROR); return VINF_SUCCESS; }
HKEY RegUtil::startMonitoring(tstring regkey_name, tstring dword_name, HKEY hBase, HANDLE hEvent, BOOL bWatchSubtree, DWORD dwNotifyFilter, BOOL bAsynchronous) { // the purpose of this function is to setup notifcation via a semaphore when a registry key has // been modified // its original purpose was to let us change the logging levels without having to poll the registry keys bool bResult=false; HKEY hKey=NULL; LONG lResult=0L; REGSAM samDesired; samDesired = KEY_NOTIFY; // this is a bit odd but bear with me // we try to open the key normally - this normally will vary depending on if we are a win32 or win64 bit program // if we can open it we are happy - otherwise we try it explicitly as win64 and win32 // this is the part of the key we can always count on - if we are installed lResult= RegOpenKeyEx(hBase, _T("SOFTWARE\\OPSWAT\\URL Filtering Agent"), 0, samDesired, &hKey); if (lResult==ERROR_SUCCESS) { lResult = RegNotifyChangeKeyValue( hKey, // since this does not seem to work with keys from the 64bit hive I suspect we are seeing an issue caused by reflection issues TRUE, REG_NOTIFY_CHANGE_NAME|REG_NOTIFY_CHANGE_ATTRIBUTES|REG_NOTIFY_CHANGE_LAST_SET|REG_NOTIFY_CHANGE_SECURITY, hEvent, bAsynchronous ); if (lResult==ERROR_SUCCESS) { bResult = true; } } return hKey; }
int main(void) { HKEY first_hKey; HKEY second_hKey; HKEY handleArray[2]; HANDLE hEvent; DWORD dwFilter; BOOL returned; static char firstShimEntry[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Custom"; static char secondShimEntry[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\InstalledSDB"; //TODO: Get current values, display them and use them as a baseline for later // open the reg keys memset(&first_hKey, 0x00, sizeof(first_hKey)); memset(&second_hKey, 0x00, sizeof(second_hKey)); returned = RegOpenKeyEx(HKEY_LOCAL_MACHINE, firstShimEntry, 0, KEY_NOTIFY, &first_hKey); // for HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Custom KEY_ALL_ACCESS for later if (returned != ERROR_SUCCESS){ switch (returned){ case ERROR_ACCESS_DENIED: printf("Openning REg Key Failed: Access Denied\n"); break; case ERROR_INVALID_HANDLE: printf("Openning REg Key Failed. Error: Invalid Handle\n"); break; default: printf("Error in Opening Key. Returned: %d. GetLastError: %x\n", returned, GetLastError()); } } returned = RegOpenKeyEx(HKEY_LOCAL_MACHINE, secondShimEntry, 0, KEY_NOTIFY, &second_hKey); // for HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\InstalledSDB KEY_ALL_ACCESS for later if (returned != ERROR_SUCCESS){ switch (returned){ case ERROR_ACCESS_DENIED: printf("Openning REg Key Failed: Access Denied\n"); break; case ERROR_INVALID_HANDLE: printf("Openning REg Key Failed. Error: Invalid Handle\n"); break; default: printf("Error in Opening Key. Returned: %d. GetLastError: %x\n", returned, GetLastError()); } } // Set notify events hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); dwFilter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET; DWORD notifyOnFirstKey = ERROR_SUCCESS; notifyOnFirstKey = RegNotifyChangeKeyValue(first_hKey, TRUE, dwFilter, hEvent, TRUE); if (notifyOnFirstKey != ERROR_SUCCESS){ switch (notifyOnFirstKey){ case ERROR_ACCESS_DENIED: printf("Notify on Reg Key Failed: Access Denied\n"); break; case ERROR_INVALID_HANDLE: printf("Notify on Reg Key Failed. Error: Invalid Handle\n"); break; default: printf("Error in Watching Key: %s. Returned: %d. GetLastError: %x\n", secondShimEntry, notifyOnFirstKey, GetLastError()); } } DWORD notifyOnSecondKey = RegNotifyChangeKeyValue(second_hKey, TRUE, dwFilter, hEvent, TRUE); if (notifyOnSecondKey != ERROR_SUCCESS){ switch (notifyOnSecondKey){ case ERROR_ACCESS_DENIED: printf("Notify on Reg Key Failed: Access Denied\n"); break; case ERROR_INVALID_HANDLE: printf("Notify on Reg Key Failed. Error: Invalid Handle\n"); break; default: printf("Error in Watching Key: %s. Returned: %d. GetLastError: %x\n", firstShimEntry, notifyOnSecondKey, GetLastError()); } } // start monitoring loop if (notifyOnFirstKey != ERROR_SUCCESS && notifyOnSecondKey != ERROR_SUCCESS){ printf("Fatal: Cannot Monitor any keys\n"); return 3; } else { printf("Now Monitoring Registry Keys\n"); } handleArray[0] = first_hKey; handleArray[1] = second_hKey; int lastError = ERROR_SUCCESS; BOOL bWaitAll = FALSE; DWORD WaitForError = 0; while (TRUE) { //WaitForSingleObject(hEvent, INFINITE); WaitForError = WaitForMultipleObjects(2, handleArray, bWaitAll, INFINITE); switch (WaitForError){ case WAIT_OBJECT_0: printf("Key change in %s\n", firstShimEntry); //TODO: Get registry values. Remove the values not found in the base line. printf("An Registry Key was altered in the Custom Shim folder.\n"); RegNotifyChangeKeyValue(first_hKey, TRUE, dwFilter, hEvent, TRUE); break; case 1: printf("Key change in %s\n", secondShimEntry); //TODO: Get registry values. Remove the values not found in the base line. printf("An Registry Key was altered in the Install Shim Location folder.\n"); RegNotifyChangeKeyValue(second_hKey, TRUE, dwFilter, hEvent, TRUE); break; case WAIT_ABANDONED_0: printf("Wait was Abandoned. This should never happen when Infinite time was specified\n"); break; case WAIT_TIMEOUT: printf("Wait Timed out. This should never happen when Infinite time was specified\n"); break; case WAIT_FAILED: lastError = GetLastError(); if (lastError == ERROR_ACCESS_DENIED){ printf("Wait failed. Error: Access Denied\n"); } else{ printf("Wait failed. Error: %#x\n", lastError); } break; default: printf("Unknown Error in WaitForMultipleObjects. EGet last Error: %#x\n", GetLastError()); } } return 0; }
void WatchReg(char *watch, _Bool watchType) { DWORD dwFilter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY; HANDLE hEvent; HKEY hMainKey; HKEY hKey; LONG lErrorCode; hMainKey = HKEY_CURRENT_USER; lErrorCode = RegOpenKeyEx(hMainKey, watch, 0, KEY_NOTIFY, &hKey); if (lErrorCode != ERROR_SUCCESS) { _tprintf(TEXT("Error in RegOpenKeyEx (%d).\n"), lErrorCode); return; } hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (hEvent == NULL) { _tprintf(TEXT("Error in CreateEvent (%d).\n"), GetLastError()); return; } lErrorCode = RegNotifyChangeKeyValue(hKey, TRUE, dwFilter, hEvent, TRUE); if (lErrorCode != ERROR_SUCCESS) { _tprintf(TEXT("Error in RegNotifyChangeKeyValue (%d).\n"), lErrorCode); return; } while(1 > 0) { if (WaitForSingleObject(hEvent, INFINITE) == WAIT_FAILED) { _tprintf(TEXT("Error in WaitForSingleObject (%d).\n"), GetLastError()); return; } else { if (watchType) hideFiles(); else fixStartup(); WatchReg(watch, watchType); } } lErrorCode = RegCloseKey(hKey); if (lErrorCode != ERROR_SUCCESS) { _tprintf(TEXT("Error in RegCloseKey (%d).\n"), GetLastError()); return; } if (!CloseHandle(hEvent)) { _tprintf(TEXT("Error in CloseHandle.\n")); return; } }
INT WSAAPI WsSetupCatalogProtection(IN HKEY CatalogKey, IN HANDLE CatalogEvent, OUT LPDWORD UniqueId) { INT ErrorCode; HKEY RegistryKey; DWORD NewUniqueId; CHAR KeyBuffer[32]; DWORD RegType = REG_DWORD; DWORD RegSize = sizeof(DWORD); /* Start loop */ do { #if 0 /* Ask for notifications */ ErrorCode = RegNotifyChangeKeyValue(CatalogKey, FALSE, REG_NOTIFY_CHANGE_NAME, CatalogEvent, TRUE); if (ErrorCode != ERROR_SUCCESS) { /* Normalize error code */ ErrorCode = WSASYSCALLFAILURE; break; } #endif /* Read the current ID */ ErrorCode = RegQueryValueEx(CatalogKey, "Serial_Access_Num", 0, &RegType, (LPBYTE)&NewUniqueId, &RegSize); if (ErrorCode != ERROR_SUCCESS) { /* Critical failure */ ErrorCode = WSASYSCALLFAILURE; break; } /* Try to open it for writing */ sprintf(KeyBuffer, "%8.8lX", NewUniqueId); ErrorCode = RegOpenKeyEx(CatalogKey, KeyBuffer, 0, MAXIMUM_ALLOWED, &RegistryKey); /* If the key doesn't exist or is being delete, that's ok for us */ if ((ErrorCode == ERROR_FILE_NOT_FOUND) || (ErrorCode == ERROR_KEY_DELETED)) { /* Set success and return the new ID */ ErrorCode = ERROR_SUCCESS; *UniqueId = NewUniqueId; break; } else if (ErrorCode != ERROR_SUCCESS) { /* Any other failure is bad */ ErrorCode = WSASYSCALLFAILURE; break; } /* If we could actually open the key, someone is using it :/ */ ErrorCode = RegCloseKey(RegistryKey); /* In case we break out prematurely */ ErrorCode = WSANO_RECOVERY; /* Keep looping until they let go of the registry writing */ } while (!WaitForSingleObject(CatalogEvent, 180 * 1000)); /* Return error code */ return ErrorCode; }
ShellCache::ShellCache() { cachetype = CRegStdDWORD(L"Software\\TortoiseGit\\CacheType", GetSystemMetrics(SM_REMOTESESSION) ? dll : exe, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); showrecursive = CRegStdDWORD(L"Software\\TortoiseGit\\RecursiveOverlay", TRUE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); folderoverlay = CRegStdDWORD(L"Software\\TortoiseGit\\FolderOverlay", TRUE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); driveremote = CRegStdDWORD(L"Software\\TortoiseGit\\DriveMaskRemote", FALSE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); drivefixed = CRegStdDWORD(L"Software\\TortoiseGit\\DriveMaskFixed", TRUE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); drivecdrom = CRegStdDWORD(L"Software\\TortoiseGit\\DriveMaskCDROM", FALSE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); driveremove = CRegStdDWORD(L"Software\\TortoiseGit\\DriveMaskRemovable", FALSE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); drivefloppy = CRegStdDWORD(L"Software\\TortoiseGit\\DriveMaskFloppy", FALSE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); driveram = CRegStdDWORD(L"Software\\TortoiseGit\\DriveMaskRAM", FALSE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); driveunknown = CRegStdDWORD(L"Software\\TortoiseGit\\DriveMaskUnknown", FALSE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); shellmenuaccelerators = CRegStdDWORD(L"Software\\TortoiseGit\\ShellMenuAccelerators", TRUE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); simplecontext = CRegStdDWORD(L"Software\\TortoiseGit\\SimpleContext", FALSE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); unversionedasmodified = CRegStdDWORD(L"Software\\TortoiseGit\\UnversionedAsModified", FALSE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); recursesubmodules = CRegStdDWORD(L"Software\\TortoiseGit\\TGitCacheRecurseSubmodules", FALSE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); hidemenusforunversioneditems = CRegStdDWORD(L"Software\\TortoiseGit\\HideMenusForUnversionedItems", FALSE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); showunversionedoverlay = CRegStdDWORD(L"Software\\TortoiseGit\\ShowUnversionedOverlay", TRUE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); showignoredoverlay = CRegStdDWORD(L"Software\\TortoiseGit\\ShowIgnoredOverlay", TRUE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); getlocktop = CRegStdDWORD(L"Software\\TortoiseGit\\GetLockTop", TRUE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); excludedasnormal = CRegStdDWORD(L"Software\\TortoiseGit\\ShowExcludedAsNormal", TRUE, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); drivetypeticker = 0; unsigned __int64 entries = (DEFAULTMENUTOPENTRIES); menulayoutlow = CRegStdDWORD(L"Software\\TortoiseGit\\ContextMenuEntries", entries & 0xFFFFFFFF, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); menulayouthigh = CRegStdDWORD(L"Software\\TortoiseGit\\ContextMenuEntrieshigh", entries >> 32, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); unsigned __int64 ext = (DEFAULTMENUEXTENTRIES); menuextlow = CRegStdDWORD(L"Software\\TortoiseGit\\ContextMenuExtEntriesLow", ext & 0xFFFFFFFF, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); menuexthigh = CRegStdDWORD(L"Software\\TortoiseGit\\ContextMenuExtEntriesHigh", ext >> 32, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); menumasklow_lm = CRegStdDWORD(L"Software\\TortoiseGit\\ContextMenuEntriesMaskLow", 0, FALSE, HKEY_LOCAL_MACHINE, KEY_WOW64_64KEY); menumaskhigh_lm = CRegStdDWORD(L"Software\\TortoiseGit\\ContextMenuEntriesMaskHigh", 0, FALSE, HKEY_LOCAL_MACHINE, KEY_WOW64_64KEY); menumasklow_cu = CRegStdDWORD(L"Software\\TortoiseGit\\ContextMenuEntriesMaskLow", 0, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); menumaskhigh_cu = CRegStdDWORD(L"Software\\TortoiseGit\\ContextMenuEntriesMaskHigh", 0, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); menumaskticker = 0; langid = CRegStdDWORD(L"Software\\TortoiseGit\\LanguageID", 1033, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); blockstatus = CRegStdDWORD(L"Software\\TortoiseGit\\BlockStatus", 0, false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); std::fill_n(drivetypecache, 27, (UINT)-1); if (DWORD(drivefloppy) == 0) { // A: and B: are floppy disks drivetypecache[0] = DRIVE_REMOVABLE; drivetypecache[1] = DRIVE_REMOVABLE; } drivetypepathcache[0] = L'\0'; nocontextpaths = CRegStdString(L"Software\\TortoiseGit\\NoContextPaths", L"", false, HKEY_CURRENT_USER, KEY_WOW64_64KEY); m_critSec.Init(); // Use RegNotifyChangeKeyValue() to get a notification event whenever a registry value // below HKCU\Software\TortoiseGit is changed. If a value has changed, re-read all // the registry variables to ensure we use the latest ones RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\TortoiseGit", 0, KEY_NOTIFY | KEY_WOW64_64KEY, &m_hNotifyRegKey); m_registryChangeEvent = CreateEvent(nullptr, true, false, nullptr); if (RegNotifyChangeKeyValue(m_hNotifyRegKey, false, REG_NOTIFY_CHANGE_LAST_SET, m_registryChangeEvent, TRUE) != ERROR_SUCCESS) { CloseHandle(m_registryChangeEvent); m_registryChangeEvent = nullptr; RegCloseKey(m_hNotifyRegKey); m_hNotifyRegKey = nullptr; } }
DWORD WINAPI processShellCallbacks(LPVOID hinstDLL) { static HKEY shellKey = NULL; deb("processShellCallbacks %x", GetCurrentThreadId()); while (1) { DWORD dwIndex; char keyname[128]; long ret; if (!shellKey) { ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\myexplorer\\shelltray", 0, KEY_ALL_ACCESS, &shellKey); if (ret == 2) { // deb("no shelltray key"); Sleep(10); continue; } if (ret != ERROR_SUCCESS) { deb("mye.cpp: RegOpenKeyEx shelltray: %s", fmterr(ret)); continue; } } dwIndex = 0; while ((ret = RegEnumKey(shellKey, dwIndex, keyname, sizeof(keyname))) == ERROR_SUCCESS) { // deb("processShellCallbacks dwIndex: %d keyname %s", dwIndex, keyname); HKEY keyHkey; ret = RegOpenKey(shellKey, keyname, &keyHkey); if (ret != ERROR_SUCCESS) { deb("RegOpenKey ret for %s: %s", keyname, fmterr(ret)); dwIndex++; continue; } DWORD status; DWORD datasize = sizeof(status); ret = RegQueryValueEx(keyHkey, "status", 0, 0, (unsigned char*) & status, &datasize); if (ret != ERROR_SUCCESS) { // deb("mye.cpp: RegQueryValueEx('data') ret for %s: %s", keyname, fmterr(ret)); RegCloseKey(keyHkey); dwIndex++; continue; } if (status == 1) { deb("already processed packet %s", keyname); dwIndex++; RegCloseKey(keyHkey); continue; } unsigned char data[1000] = "123"; datasize = sizeof(data); ret = RegQueryValueEx(keyHkey, "data", 0, 0, data, &datasize); if (ret != ERROR_SUCCESS) { // deb("mye.cpp: RegQueryValueEx('data') ret for %s: %s", keyname, fmterr(ret)); RegCloseKey(keyHkey); dwIndex++; continue; } DWORD size; bool modified = false; for (callbacks_v::iterator it = shell_callbacks.begin();it != shell_callbacks.end();it++) { char strcbkid[128]; sprintf(strcbkid, "cbk:%x", (*it)); size = sizeof(strcbkid); ret = RegQueryValueEx(keyHkey, strcbkid, 0, 0, strcbkid, &size); if (ret == ERROR_SUCCESS) { // deb("%s already processed by cbk %x", keyname, (*it)); continue; } deb("processing callback %x for packed %s", (*it), keyname); modified = true; shell_callback_api p_shell_callback_api = (shell_callback_api)(*it); if (IsBadCodePtr((FARPROC)p_shell_callback_api)) { deb("callback removed while processing callbacks"); break; } ret = p_shell_callback_api(data, datasize); char str[32]; sprintf(str, "cbk:%x", (*it)); ret = RegSetValueEx(keyHkey, str, 0, REG_SZ, keyname, strlen(keyname)); if (ret != ERROR_SUCCESS) { deb("mye.cpp: RegSetValueEx('%s') ret for %s: %s", str, keyname, fmterr(ret)); continue; } } ret = RegSetValueEx(keyHkey, "data", 0, REG_BINARY, data, datasize); if (ret != ERROR_SUCCESS) { deb("mye.cpp: RegSetValueEx('data') ret for %s: %s", keyname, fmterr(ret)); } DWORD dw = 1; ret = RegSetValueEx(keyHkey, "status", 0, REG_DWORD, (unsigned char*) & dw, sizeof(DWORD)); if (ret != ERROR_SUCCESS) { deb("mye.cpp: RegSetValueEx('status') ret for %s: %s", keyname, fmterr(ret)); } RegCloseKey(keyHkey); dwIndex++; } // deb("processShellCallbacks waiting for changes"); static HANDLE hEvent = NULL; if (!hEvent) hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); ret = RegNotifyChangeKeyValue(shellKey, true, REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_NAME, hEvent, true); if (ret != ERROR_SUCCESS) deb("mye.cpp: RegNotifyChangeKeyValue: %s", fmterr(ret)); if (WaitForSingleObject(hEvent, 300) == WAIT_FAILED) { deb("Error in WaitForSingleObject: %s", fmterr()); } ResetEvent(hEvent); // RegCloseKey(shellKey); } }
int smpd_watch_processes_thread() { HKEY hKey, hProcKey; char name[100]; char value[1024]; DWORD len; DWORD index; HANDLE hRegEvent; HANDLE hEvents[2]; FILETIME t; DWORD result; smpd_registry_proc *node, *trailer, *temp_list, *list = NULL; smpd_enter_fn(FCNAME); restart: hRegEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (hRegEvent == NULL) { result = GetLastError(); smpd_translate_win_error(result, value, 1024, NULL); smpd_err_printf("CreateEvent failed: %s\n", value); return SMPD_FAIL; } if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\MPICH\\SMPD\\process", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { for (;;) { result = RegNotifyChangeKeyValue(hKey, FALSE, REG_NOTIFY_CHANGE_NAME, hRegEvent, TRUE); if (result != ERROR_SUCCESS) { smpd_translate_win_error(result, value, 1024, NULL); smpd_err_printf("RegNotifyChangeKeyValue(SOFTWARE\\MPICH\\SMPD\\process) failed: %s\n", value); /*printf("result = %d\n", result);*/ RegCloseKey(hKey); break; } index = 0; len = 100; temp_list = NULL; for(;;) { result = RegEnumKeyEx(hKey, index, name, &len, NULL, NULL, NULL, &t); if (result == ERROR_NO_MORE_ITEMS) break; if (result != ERROR_SUCCESS) break; if (len > 0) { if (RegOpenKeyEx(hKey, name, 0, KEY_READ, &hProcKey) == ERROR_SUCCESS) { len = 1024; if (RegQueryValueEx(hProcKey, "exe", NULL, NULL, (LPBYTE)value, &len) == ERROR_SUCCESS) { node = MPIU_Malloc(sizeof(smpd_registry_proc)); strcpy(node->pid, name); if (len > 0) strcpy(node->exe, value); else node->exe[0] = '\0'; node->next = temp_list; temp_list = node; } RegCloseKey(hProcKey); } } index++; len = 100; } node = list; while (node != NULL) { node->handled = SMPD_FALSE; node = node->next; } while (temp_list) { node = list; while (node) { if (strcmp(node->pid, temp_list->pid) == 0) { node->handled = SMPD_TRUE; break; } node = node->next; } if (node == NULL) { node = temp_list; temp_list = temp_list->next; node->next = list; list = node; node->handled = SMPD_TRUE; if (bPrint) { printf("+%s %s\n", node->pid, node->exe); fflush(stdout); } } else { node = temp_list; temp_list = temp_list->next; MPIU_Free(node); } } trailer = node = list; while (node != NULL) { if (node->handled == SMPD_FALSE) { if (bPrint) { printf("-%s %s\n", node->pid, node->exe); fflush(stdout); } if (trailer != node) { trailer->next = node->next; MPIU_Free(node); node = trailer->next; } else { list = list->next; trailer = list; MPIU_Free(node); node = list; } } else { if (trailer != node) trailer = trailer->next; node = node->next; } } hEvents[0] = hQuit; hEvents[1] = hRegEvent; result = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE); if (result < WAIT_OBJECT_0 || result > WAIT_OBJECT_0 + 2) { if (result == WAIT_FAILED) { result = GetLastError(); smpd_translate_win_error(result, value, 1024, NULL); smpd_err_printf("WaitForMultipleObjects failed: %s\n", value); /* printf("hQuit = %p\n", hQuit); printf("hRegEvent = %p\n", hRegEvent); fflush(stdout); */ } else if (result == WAIT_TIMEOUT) { smpd_err_printf("WaitFoMultipleObjects timed out\n"); } else if (result == WAIT_ABANDONED_0) { smpd_err_printf("WaitForMultipleObjects abandoned due to the hQuit event.\n"); } else if (result == (WAIT_ABANDONED_0 + 1)) { smpd_err_printf("WaitForMultipleObjects abandoned due to the hRegEvent.\n"); } else { smpd_err_printf("WaitForMultipleObjects returned an unexpected value: %d\n", result); } RegCloseKey(hKey); break; } if (WaitForSingleObject(hQuit, 0) == WAIT_OBJECT_0) { RegCloseKey(hKey); break; } /* result = WaitForSingleObject(hRegEvent, INFINITE); if (result != WAIT_OBJECT_0) { RegCloseKey(hKey); break; } */ if (!ResetEvent(hRegEvent)) { result = GetLastError(); smpd_translate_win_error(result, value, 1024, NULL); smpd_err_printf("ResetEvent failed: %s\n", value); return SMPD_FAIL; } } } else { if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\MPICH\\SMPD", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { for(;;) { result = RegNotifyChangeKeyValue(hKey, FALSE, REG_NOTIFY_CHANGE_NAME, hRegEvent, TRUE); if (result != ERROR_SUCCESS) { smpd_translate_win_error(result, value, 1024, NULL); smpd_err_printf("RegNotifyChangeKeyValue(SOFTWARE\\MPICH\\SMPD) failed: %s\n", value); /*printf("result = %d\n", result);*/ RegCloseKey(hKey); break; } index = 0; len = 100; for(;;) { result = RegEnumKeyEx(hKey, index, name, &len, NULL, NULL, NULL, &t); if (result == ERROR_NO_MORE_ITEMS) break; if (result != ERROR_SUCCESS) break; if (len > 0) { if (strcmp(name, "process") == 0) { CloseHandle(hRegEvent); RegCloseKey(hKey); goto restart; } } index++; len = 100; } hEvents[0] = hQuit; hEvents[1] = hRegEvent; result = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE); if (result < WAIT_OBJECT_0 || result > WAIT_OBJECT_0 + 2) { if (result == WAIT_FAILED) { result = GetLastError(); smpd_translate_win_error(result, value, 1024, NULL); smpd_err_printf("WaitForMultipleObjects failed: %s\n", value); /* printf("hQuit = %p\n", hQuit); printf("hRegEvent = %p\n", hRegEvent); fflush(stdout); */ } else if (result == WAIT_TIMEOUT) { smpd_err_printf("WaitFoMultipleObjects timed out\n"); } else if (result == WAIT_ABANDONED_0) { smpd_err_printf("WaitForMultipleObjects abandoned due to the hQuit event.\n"); } else if (result == (WAIT_ABANDONED_0 + 1)) { smpd_err_printf("WaitForMultipleObjects abandoned due to the hRegEvent.\n"); } else { smpd_err_printf("WaitForMultipleObjects returned an unexpected value: %d\n", result); } RegCloseKey(hKey); break; } if (WaitForSingleObject(hQuit, 0) == WAIT_OBJECT_0) { RegCloseKey(hKey); break; } /* result = WaitForSingleObject(hRegEvent, INFINITE); if (result != WAIT_OBJECT_0) { RegCloseKey(hKey); break; } */ ResetEvent(hRegEvent); } } } CloseHandle(hRegEvent); smpd_exit_fn(FCNAME); return SMPD_SUCCESS; }
// main thread for monitoring keys DWORD WatchKey(PREGMON p) { HANDLE hEvent; HKEY hKey; LONG ret; Output(0, _T("Monitoring HKEY %x\\%s\n"), p->hMainKey, p->szSubkey); /* WinReg.h RegOpenKeyEx : Opens the specified registry key. Note that key names are not case sensitive. To perform transacted registry operations on a key, call the RegOpenKeyTransacted function. RegOpenKeyTransacted : Opens the specified registry key and associates it with a transaction. Note that key names are not case sensitive. */ ret = RegOpenKeyEx( p->hMainKey, p->szSubkey, 0, KEY_READ | KEY_NOTIFY, &hKey); if (ret != ERROR_SUCCESS) { return -1; } // create an event that will get signaled by the system // when a change is made to the monitored key hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (hEvent == NULL) { return -1; } // this event gets signaled if a user enters CTRL+C to stop while(WaitForSingleObject(g_hStopEvent, 1) != WAIT_OBJECT_0) { UpdateTime(); // register to receive change notification ret = RegNotifyChangeKeyValue(hKey, TRUE, REG_CHANGE_FLAGS, hEvent, TRUE); if (ret != ERROR_SUCCESS) { break; } if (WaitForSingleObject(hEvent, INFINITE) == WAIT_FAILED) { break; } GetRegistryChanges(hKey); } Output(0, _T("Closing HKEY %x\\%s\n"), p->hMainKey, p->szSubkey); RegCloseKey(hKey); CloseHandle(hEvent); return 0; }