• C

How to use RegNotifyChangeKeyValue with a thread in c++

How to use RegNotifyChangeKeyValue with a thread in c++
Eric_974Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

parnassoCommented:
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
parnassoCommented:
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
Eric_974Author Commented:
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
Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

parnassoCommented:
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
Eric_974Author Commented:
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
parnassoCommented:
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
parnassoCommented:
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
Eric_974Author Commented:
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
parnassoCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Deepu AbrahamR & D Engineering ManagerCommented:
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.