Question : C++ - Calling 'RegDeleteValue' in between 'RegEnumValue' causes 'RegEnumValue' to fail

Hi,
I need to do the following. Enumerate the value in a ragistry key and get the values one at a time. Based on some comparison results, I may have to delete a value, after it is read. I've done the code as below:
My problem is that after a call to 'RegDeleteValue' the next call to 'RegEnumValue'  returns 'ERROR_NO_MORE_ITEMS ' although there are other items remaining to be read.
Is it wrong to call the delete function in between the enumerate function?
If so, is there another way I can do this?

Regards,
hj
Code Snippet:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
//reg_key = HKLM\SOFTWARE\KEYNAME
if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE ,
		                             reg_key , 0 ,
									 KEY_QUERY_VALUE|KEY_SET_VALUE , &hkey) )
	{
		TCHAR    achClass[MAX_PATH] = TEXT("");  // buffer for class name 
		DWORD    cchClassName = MAX_PATH;  // size of class string 
		DWORD    cSubKeys=0;               // number of subkeys 
		DWORD    cbMaxSubKey;              // longest subkey size 
		DWORD    cchMaxClass;              // longest class string 
		DWORD    cValues;              // number of values for key 
		DWORD    cchMaxValue;          // longest value name 
		DWORD    cbMaxValueData;       // longest value data 
		DWORD    cbSecurityDescriptor; // size of security descriptor 
		FILETIME ftLastWriteTime;      // last write time 
	 
		DWORD i, retCode; 
	  
		TCHAR  achValue[MAX_VALUE_NAME]; //MAX_VALUE_NAME = 5
		DWORD cchValue = MAX_VALUE_NAME;

	 
		// Get the class name and the value count. 
		retCode = RegQueryInfoKey(
			hkey,                    // key handle 
			achClass,                // buffer for class name 
			&cchClassName,           // size of class string 
			NULL,                    // reserved 
			&cSubKeys,               // number of subkeys 
			&cbMaxSubKey,            // longest subkey size 
			&cchMaxClass,            // longest class string 
			&cValues,                // number of values for this key 
			&cchMaxValue,            // longest value name 
			&cbMaxValueData,         // longest value data 
			&cbSecurityDescriptor,   // security descriptor 
			&ftLastWriteTime);       // last write time 

		    // Enumerate the key values. 

		if (cValues)
		{
			num_vals = cValues;
			if(reg_vals == NULL)
			{
				reg_vals = new char[num_vals * 5];
				SecureZeroMemory(reg_vals, ( (num_vals * 5) * sizeof(char) ) );
			}

			for (i=0, retCode=ERROR_SUCCESS; i < cValues; i++) 
			{ 
				cchValue = MAX_VALUE_NAME; 
				achValue[0] = '\0'; 
				retCode = RegEnumValue(hkey, i, 
					achValue, 
					&cchValue, 
					NULL, 
					NULL,
					NULL,
					NULL);
	 
				if (retCode == ERROR_SUCCESS ) 
				{ 
					//Check for incorrect values
					if( strlen(achValue) != (val_size - 1) )
					{
						//Delete the errenous value
						RegDeleteValue(hkey,achValue);
						achValue[0] = '\0';
						num_vals--;
					}
					else
					{
						//Get the registry values into the 'reg_vals' array
						strncpy_s((reg_vals + (i * val_size ) ), 5, achValue, strlen(achValue));
						reg_vals[(i * val_size )+ strlen(achValue) ] = ',';
					}
				} 
			}
				reg_vals[( (i-1) * val_size )+ strlen(achValue) ] = '\0';		}
		RegCloseKey(hkey);
	}

Answer : C++ - Calling 'RegDeleteValue' in between 'RegEnumValue' causes 'RegEnumValue' to fail

Sorry again. I did it too fast. The following code works for me. It uses Multi-Byte Character set now.
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
#include 
#include 

static const LPCSTR s_szKey = "SOFTWARE\\Test";

int main()
{
	HKEY hKey = NULL;
	DWORD nIndex = 0;
	DWORD nValue = 1024;
	CHAR szValue[1024] = { 0 };
	LONG nRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, s_szKey, 
		0, KEY_READ | KEY_WRITE, &hKey);

	if (hKey == NULL)
		return 0;

	while (RegEnumValue(hKey, nIndex, szValue, &nValue, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
	{
		printf("\t %d. name = %s\n", nIndex, szValue);
		if (strlen(szValue) < 5)
		{ 
			RegDeleteValue(hKey, szValue); 
			nIndex = 0;
			printf("\t %d. name = %s. Deleted.\n", nIndex, szValue); 
		} 
		else
			nIndex++;
		ZeroMemory(szValue, 1024); 
		nValue = 1024; 
	}

	RegCloseKey(hKey);
	return 0;
}
Random Solutions  
 
programming4us programming4us