int MonitoringRegChange( WCHAR *pwKey )
{
DWORD dwFilter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET;
HKEY hKey = NULL;
LONG lErrorCode = ::RegOpenKeyEx( HKEY_CURRENT_USER, pwKey, 0, KEY_NOTIFY, &hKey);
if ( lErrorCode != ERROR_SUCCESS )
{
if ( lErrorCode != ERROR_FILE_NOT_FOUND )
{
return -1;
}
lErrorCode = RegCreateKeyEx( HKEY_CURRENT_USER, pwKey, 0, NULL, 0, KEY_NOTIFY,
NULL, &hKey, NULL) ;
if ( lErrorCode != ERROR_SUCCESS )
{
return -1;
}
}
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (hEvent == NULL)
{
CloseHandle(hEvent);
RegCloseKey(hKey);
return -1;
}
HANDLE hEvents[2];
hEvents[0] = m_hExitEvent;
hEvents[1] = hEvent;
while( TRUE )
{
lErrorCode = RegNotifyChangeKeyValue( hKey, TRUE, dwFilter, hEvent, TRUE );
if (lErrorCode != ERROR_SUCCESS) // Reg감시중, key삭제되는경우의복구루틴
{
RegCloseKey(hKey);
if ( lErrorCode != ERROR_KEY_DELETED )
{
return -1;
}
lErrorCode = RegCreateKeyEx( HKEY_CURRENT_USER, pwKey, 0, NULL, 0,
KEY_NOTIFY, NULL, &hKey, NULL) ;
if ( lErrorCode != ERROR_SUCCESS )
{
return -1;
}
// Detect Registry Changed – Key is Deleted
continue;
}
if ( WaitForSingleObject( hEvent, 0 ) == WAIT_OBJECT_0 )
{
// 첫번째 RegNotifyChangeKeyValue() Call과두번째 RegNotifyChangeKeyValue()
// Call사이에 변경이있을경우, Envent가 바로활성화되어,
// 한번의 레지스트리 변경에 대해 두번의 noty를받게되는 문제 Fix
// http://support.microsoft.com/kb/236570/en-us
lErrorCode = RegNotifyChangeKeyValue( hKey, TRUE, dwFilter, hEvent, TRUE );
if (lErrorCode != ERROR_SUCCESS)
{
CloseHandle(hEvent);
RegCloseKey(hKey);
return -1;
}
}
DWORD dwResult = ::WaitForMultipleObjects( 2, hEvents, FALSE, INFINITE );
if ( dwResult == WAIT_FAILED )
{
CloseHandle(hEvent);
RegCloseKey(hKey);
return -1;
}
else if ( dwResult == WAIT_OBJECT_0 )
{
// recevie Stop monitoring noty
return 0;
}
else if ( dwResult == WAIT_OBJECT_0 + 1 )
{
// Detect Registry Changed
continue;
}
}
CloseHandle(hEvent);
RegCloseKey(hKey);
return 0;
} |