Solved

How to use RegNotifyChangeKeyValue with a thread in c++

Posted on 2011-03-08
10
1,089 Views
Last Modified: 2012-05-11
How to use RegNotifyChangeKeyValue with a thread in c++
0
Comment
Question by:Eric_974
  • 6
  • 3
10 Comments
 
LVL 4

Expert Comment

by:parnasso
ID: 35068154
The idea is to have a worker thread waiting for an event to be singaled.
If this fits your needs, you should:

1

Create an event with CreateEvent

2

Create a thread, pass the event handler to it, and call WaitForSingleObject

3

Call RegNotifyChangeKeyValue passing the event as the fourth parameter and TRUE in the fifth parameter (fAsynchronous ) TRUE)

hope this helps
0
 
LVL 4

Expert Comment

by:parnasso
ID: 35068206
I forgot to mention that within the created thread, in order to receive more than one event from the registry, you have to call RegNotifyChangeKeyValue after you receive the registry event (after WaitForSingleObject)
0
 

Author Comment

by:Eric_974
ID: 35068877
Thank's to reply. But im not sure to inderstand the second answer. Effectly I receive only one event. But why ? Here is my code :

HANDLE	handle_event = NULL, handle_thread = NULL;

DWORD	dwFilter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY; 
HKEY	h_key_register;

DWORD WINAPI
Func_Thread (LPVOID lpParam) 
{
	lpParam;
	DWORD	dwWaitResult;

	dwWaitResult = WaitForSingleObject (handle_event, INFINITE);
	switch (dwWaitResult) {
		case WAIT_OBJECT_0:
...
			break; 
		
		default: 
			return 0; 
	}
    return 1;
}

void
Run_Thread ()
{
	DWORD	num_thread;

	handle_event = CreateEvent (NULL, TRUE, FALSE, "Register Event");
	handle_thread = CreateThread (NULL, 0, Func_Thread, NULL, 0, &num_thread); 
	if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_NOTIFY, &h_key_register) == ERROR_SUCCESS)
		RegNotifyChangeKeyValue (h_key_register, TRUE, dwFilter, handle_event, TRUE);
}

Open in new window

0
Back Up Your Microsoft Windows Server®

Back up all your Microsoft Windows Server – on-premises, in remote locations, in private and hybrid clouds. Your entire Windows Server will be backed up in one easy step with patented, block-level disk imaging. We achieve RTOs (recovery time objectives) as low as 15 seconds.

 
LVL 4

Expert Comment

by:parnasso
ID: 35069027
In the function func_thread please call RegNotifyChangeValue again keeping the same registry open handle,  like this:

HANDLE	handle_event = NULL, handle_thread = NULL;

DWORD	dwFilter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY; 
HKEY	h_key_register;

DWORD WINAPI
Func_Thread (LPVOID lpParam) 
{
	lpParam;
	DWORD	dwWaitResult;

	dwWaitResult = WaitForSingleObject (handle_event, INFINITE);
	switch (dwWaitResult) {
		case WAIT_OBJECT_0:
                   // do something ...
                   // reissue the notify command
                   RegNotifyChangeKeyValue (h_key_register, TRUE, dwFilter, handle_event, TRUE);
			break; 
		
		default: 
			return 0; 
	}
    return 1;
}

void
Run_Thread ()
{
	DWORD	num_thread;

        if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_NOTIFY, &h_key_register) == ERROR_SUCCESS)
        {
	     handle_event = CreateEvent (NULL, TRUE, FALSE, "Register Event");
	     handle_thread = CreateThread (NULL, 0, Func_Thread, NULL, 0, &num_thread); 
	
	     RegNotifyChangeKeyValue (h_key_register, TRUE, dwFilter, handle_event, TRUE);
         }
}

Open in new window

0
 

Author Comment

by:Eric_974
ID: 35069482
Thank's again for your answer. But i am sorry nothing happen after the first even !! I explain what i want to do :
I have a serial com on USB port. I need to know in my application when the serial/USB port has been unplugged and/or plugged at any time.

Thanks a lot for help
0
 
LVL 4

Expert Comment

by:parnasso
ID: 35069632
Don't surrender. Let's try another thing I've in my mind.
Create the event with autoreset in the line 33, that is:

 handle_event = CreateEvent (NULL, FALSE, FALSE, "Register Event");

I hope that was the problem!
0
 
LVL 4

Expert Comment

by:parnasso
ID: 35069670
Forget what I-ve posted before, I've found the issue: after the thread gets signaled it returns and never come back to another WaitForSingleObject. So I added an infite loop:

HANDLE	handle_event = NULL, handle_thread = NULL;

DWORD	dwFilter = REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY; 
HKEY	h_key_register;

DWORD WINAPI
Func_Thread (LPVOID lpParam) 
{
	lpParam;
	DWORD	dwWaitResult;
        
         while(1)
         {

	   dwWaitResult = WaitForSingleObject (handle_event, INFINITE);
	   switch (dwWaitResult) {
		case WAIT_OBJECT_0:
                   // do something ...
                   // reissue the notify command
                   RegNotifyChangeKeyValue (h_key_register, TRUE, dwFilter, handle_event, TRUE);
			break; 
		
		default: 
			return 0; 
              }
	}
    return 1;
}

void
Run_Thread ()
{
	DWORD	num_thread;

        if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_NOTIFY, &h_key_register) == ERROR_SUCCESS)
        {
	     handle_event = CreateEvent (NULL, TRUE, FALSE, "Register Event");
	     handle_thread = CreateThread (NULL, 0, Func_Thread, NULL, 0, &num_thread); 
	
	     RegNotifyChangeKeyValue (h_key_register, TRUE, dwFilter, handle_event, TRUE);
         }
}

Open in new window

0
 

Author Comment

by:Eric_974
ID: 35069804
Thanks a lot. It's works ! A last question. How can i know with event has occur ?  REG_NOTIFY_CHANGE_NAME, REG_NOTIFY_CHANGE_ATTRIBUTES, REG_NOTIFY_CHANGE_LAST_SET or REG_NOTIFY_CHANGE_SECURITY ?
0
 
LVL 4

Accepted Solution

by:
parnasso earned 250 total points
ID: 35070348
Sorry, with this approach, i don't know how to get which event occured just after the event is signaled. For sure you have to do some workaround or do some research to try with another approach. The following post might help you:

Register for USB arrival
0
 
LVL 11

Assisted Solution

by:DeepuAbrahamK
DeepuAbrahamK earned 250 total points
ID: 35081992
To answer your last question:

Note: I haven't compiled it yet but this should help I guess.
DWORD  dwFilter = 0x00;
   HEVENT hEvent[4];


   for (int i = 0; i<4; i++)
   {
      hEvent[0] = CreateEvent(NULL, TRUE, FALSE, NULL);
   }

   dwFilter = REG_NOTIFY_CHANGE_NAME;
   lErrorCode = RegNotifyChangeKeyValue(hKey, 
                                        TRUE, 
                                        dwFilter, 
                                        hEvent[0], 
                                        TRUE);


   dwFilter = REG_NOTIFY_CHANGE_ATTRIBUTES;
   lErrorCode = RegNotifyChangeKeyValue(hKey, 
                                        TRUE, 
                                        dwFilter, 
                                        hEvent[1], 
                                        TRUE);


   dwFilter = REG_NOTIFY_CHANGE_LAST_SET;
   lErrorCode = RegNotifyChangeKeyValue(hKey, 
                                        TRUE, 
                                        dwFilter, 
                                        hEvent[2], 
                                        TRUE);

   dwFilter = REG_NOTIFY_CHANGE_SECURITY; 
   lErrorCode = RegNotifyChangeKeyValue(hKey, 
                                        TRUE, 
                                        dwFilter, 
                                        hEvent[3], 
                                        TRUE);

    dwEvent = WaitForMultipleObjects( 
        4,           // number of objects in array
        hEvent,     // array of objects
        FALSE,       // wait for any object
        5000);       // five-second wait
	
   switch (dwEvent) 
   { 
        // hEvent[0] was signaled or REG_NOTIFY_CHANGE_NAME occurred
        case WAIT_OBJECT_0 + 0: 
            printf("REG_NOTIFY_CHANGE_NAME event was signaled.\n");
            break; 

        // hEvent[1] was signaled or REG_NOTIFY_CHANGE_ATTRIBUTES occurred
        case WAIT_OBJECT_0 + 1: 
            printf("REG_NOTIFY_CHANGE_ATTRIBUTES event was signaled.\n");
            break;

        // hEvent[2] was signaled or REG_NOTIFY_CHANGE_LAST_SET occurred
        case WAIT_OBJECT_0 + 2: 
            printf("REG_NOTIFY_CHANGE_LAST_SET event was signaled.\n");
            break;
   
       // hEvent[3] was signaled or REG_NOTIFY_CHANGE_SECURITY occurred
        case WAIT_OBJECT_0 + 3: 
            printf("REG_NOTIFY_CHANGE_SECURITY event was signaled.\n");
            break;
   }

Open in new window

0

Featured Post

Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

803 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question