I am writing this with a sense of defeat. In my post about monitoring for registry changes (see Windows CE: Monitor for Registry Changes) I showed how to monitor for registry changes using CeFindFirstRegChange() and CeFindNextRegChange() but left the code for determining what changed empty. Honestly, I gave it a shot with the new function CeRegGetNotificationInfo() available in Windows CE 6.0. I simply cannot get it to work, and my searching on the WEB didn’t turn up anything that tells me that it does work (unless you count the MSDN documentation.)
So, I decided to post the code here for review and would love to hear from you if you have suggestions. The following code fits into the monitor code that I posted earlier.
                RETAILMSG( 1, (TEXT("Found reg change\r\n")));
                if( CeRegGetNotificationInfo( hFind, 0, NULL, 0, NULL, &BytesAvailable ) )
                                RETAILMSG( 1, (TEXT("CeRegGetNotificationInfo failed %d\r\n"), GetLastError() ));
                RETAILMSG( 1, (TEXT("Bytes Available %X\r\n"), BytesAvailable ));
                if( BytesAvailable == 0 )
                                RETAILMSG( 1, (TEXT("No data\r\n")));
                if( !CeRegGetNotificationInfo( NULL, 0, NULL, 0, NULL, NULL ) )
                                RETAILMSG( 1, (TEXT("CeRegGetNotificationInfo failed %d\r\n"), GetLastError() ));
                if( !CeRegGetNotificationInfo( hFind, 0, NULL, 0, NULL, NULL ) )
                                RETAILMSG( 1, (TEXT("CeRegGetNotificationInfo failed %d\r\n"), GetLastError() ));
                BytesAvailable = 1024;
                RegInfo = (REG_NOTIFY_INFORMATION *)malloc( BytesAvailable );
                if( RegInfo && !CeRegGetNotificationInfo( hFind, 0, RegInfo, BytesAvailable, &BytesReturned, &BytesAvailable ) )
                                RETAILMSG( 1, (TEXT("BA %d BR %d\r\n"), BytesAvailable, BytesReturned ));
                                NextRegInfo = RegInfo;
                                while( NextRegInfo->NextEntryOffset )
                                                switch( NextRegInfo->Action )
                                                                case FILE_ACTION_ADDED:
                                                                                RETAILMSG( 1, (TEXT("Action Added\r\n")));
                                                                case FILE_ACTION_MODIFIED:
                                                                                RETAILMSG( 1, (TEXT("Action Modified\r\n")));
                                                                case FILE_ACTION_REMOVED:
                                                                                RETAILMSG( 1, (TEXT("Action Deleted\r\n")));
                                                if( NextRegInfo->RegNameLength )
                                                                TCHAR *RegStr = (TCHAR *)malloc((NextRegInfo->RegNameLength + 1 ) * sizeof(TCHAR));
                                                                wcsncpy( RegStr, NextRegInfo->RegName, NextRegInfo->RegNameLength );
                                                                RegStr[ NextRegInfo->RegNameLength ] = '\0';
                                                                RETAILMSG( 1, (TEXT("Changed %s\r\n"), RegStr ));
                                                                free( RegStr );
                                                NextRegInfo = (REG_NOTIFY_INFORMATION*)( (DWORD)NextRegInfo + NextRegInfo->NextEntryOffset );
                                RETAILMSG( 1, (TEXT("CeGetFileNotificationInfo failed\r\n")));
                free( RegInfo );
                CeFindNextRegChange( hFind );
The new variable declarations are:
                REG_NOTIFY_INFORMATION *RegInfo;
                REG_NOTIFY_INFORMATION *NextRegInfo;
                DWORD BytesAvailable = 0xa5a5;
                DWORD BytesReturned;
You will notice some oddities in the code above. I tried to get it to fail by calling CeRegGetNotificationInfo() with all invalid parameters, and it does fail with an invalid handle returned by GetLastError(). But if I pass in a valid handle and the other parameters as invalid, it succeeds. But, I should point out that I had to ignore the documentation and look for zero for failure and non-zero for success – or actually it seems that it only returns zero.
Finally, I tried forcing the allocation of data, but still no results.
Copyright © 2009 – Bruce Eitman
All Rights Reserved