formats/settings/m_settings_writer.c
/* This function recursivly goes though every key, deletes each value and then the key
 * itself. RegDeleteTree function could be used instead but it requires "Vista" as
 * the minimum OS version. */
This function recursivly goes though every key, deletes each value and then the key
itself. RegDeleteTree function could be used instead but it requires "Vista" as
the minimum OS version.
This function recursivly goes though every key deletes each value and then the key itself . RegDeleteTree function could be used instead but it requires " Vista " as the minimum OS version .
static M_bool M_settings_write_registry_clear(HKEY hkey, const char *location)
{
	char   *subkey;
	char   *name;
	HKEY    shkey;
	DWORD   subname_max      = 0;
	DWORD   temp_subname_max = 0;
	DWORD   valname_max      = 0;
	DWORD   temp_valname_max = 0;
	LONG    ret;
	subkey = M_settings_reg_path(location);
	ret = RegOpenKeyEx(hkey, subkey, 0, KEY_READ|KEY_WRITE, &shkey);
	M_free(subkey);
	if (ret == ERROR_FILE_NOT_FOUND)
		return M_TRUE;
	if (ret != ERROR_SUCCESS)
		return M_FALSE;
	ret = RegQueryInfoKey(shkey, NULL, 0, NULL, NULL, &subname_max, NULL, NULL, &valname_max, NULL, NULL, NULL);
	if (ret != ERROR_SUCCESS) {
		RegCloseKey(shkey);
		return M_FALSE;
	}
	name = M_malloc_zero(valname_max+1);
	while (1) {
		temp_valname_max = valname_max+1;
		name[0]          = '\0';
		ret              = RegEnumValue(shkey, 0, (LPTSTR)name, &temp_valname_max, NULL, NULL, NULL, NULL);
		if (ret == ERROR_NO_MORE_ITEMS) {
			break;
		} else if (ret != ERROR_SUCCESS) {
			M_free(name);
			RegCloseKey(shkey);
			return M_FALSE;
		}
		ret = RegDeleteValue(shkey, name);
		if (ret != ERROR_SUCCESS) {
			M_free(name);
			RegCloseKey(shkey);
			return M_FALSE;
		}
	}
	M_free(name);
	name = M_malloc(subname_max+1);
	while (1) {
		temp_subname_max = subname_max+1;
		name[0]          = '\0';
		ret              = RegEnumKeyEx(shkey, 0, (LPTSTR)name, &temp_subname_max, NULL, NULL, NULL, NULL);
		if (ret == ERROR_NO_MORE_ITEMS) {
			break;
		} else if (ret != ERROR_SUCCESS) {
			M_free(name);
			RegCloseKey(shkey);
			return M_FALSE;
		}
		if (!M_settings_write_registry_clear(shkey, name)) {
			M_free(name);
			RegCloseKey(shkey);
			return M_FALSE;
		}
		ret = RegDeleteKey(shkey, name);
		if (ret != ERROR_SUCCESS) {
			M_free(name);
			RegCloseKey(shkey);
			return M_FALSE;
		}
	}
	M_free(name);
	RegCloseKey(shkey);
	return M_TRUE;
}
static M_bool M_settings_write_registry_clear ( HKEY hkey , const char * location ) { char * subkey ; char * name ; HKEY shkey ; DWORD subname_max = 0 ; DWORD temp_subname_max = 0 ; DWORD valname_max = 0 ; DWORD temp_valname_max = 0 ; LONG ret ; subkey = M_settings_reg_path ( location ) ; ret = RegOpenKeyEx ( hkey , subkey , 0 , KEY_READ | KEY_WRITE , & shkey ) ; M_free ( subkey ) ; if ( ret == ERROR_FILE_NOT_FOUND ) return M_TRUE ; if ( ret != ERROR_SUCCESS ) return M_FALSE ; ret = RegQueryInfoKey ( shkey , NULL , 0 , NULL , NULL , & subname_max , NULL , NULL , & valname_max , NULL , NULL , NULL ) ; if ( ret != ERROR_SUCCESS ) { RegCloseKey ( shkey ) ; return M_FALSE ; } name = M_malloc_zero ( valname_max + 1 ) ; while ( 1 ) { temp_valname_max = valname_max + 1 ; name [ 0 ] = ' \0 ' ; ret = RegEnumValue ( shkey , 0 , ( LPTSTR ) name , & temp_valname_max , NULL , NULL , NULL , NULL ) ; if ( ret == ERROR_NO_MORE_ITEMS ) { break ; } else if ( ret != ERROR_SUCCESS ) { M_free ( name ) ; RegCloseKey ( shkey ) ; return M_FALSE ; } ret = RegDeleteValue ( shkey , name ) ; if ( ret != ERROR_SUCCESS ) { M_free ( name ) ; RegCloseKey ( shkey ) ; return M_FALSE ; } } M_free ( name ) ; name = M_malloc ( subname_max + 1 ) ; while ( 1 ) { temp_subname_max = subname_max + 1 ; name [ 0 ] = ' \0 ' ; ret = RegEnumKeyEx ( shkey , 0 , ( LPTSTR ) name , & temp_subname_max , NULL , NULL , NULL , NULL ) ; if ( ret == ERROR_NO_MORE_ITEMS ) { break ; } else if ( ret != ERROR_SUCCESS ) { M_free ( name ) ; RegCloseKey ( shkey ) ; return M_FALSE ; } if ( ! M_settings_write_registry_clear ( shkey , name ) ) { M_free ( name ) ; RegCloseKey ( shkey ) ; return M_FALSE ; } ret = RegDeleteKey ( shkey , name ) ; if ( ret != ERROR_SUCCESS ) { M_free ( name ) ; RegCloseKey ( shkey ) ; return M_FALSE ; } } M_free ( name ) ; RegCloseKey ( shkey ) ; return M_TRUE ; }
This function recursivly goes though every key, deletes each value and then the key
 itself.
This function recursivly goes though every key deletes each value and then the key itself .
/* Open the location. */ /* If the location doesn't exist were done. No error. */ /* If we can't open the location (and it exists) we have an error. */ /* Get info about sub keys.
 	 *
	 * Note:
	 *
	 * RegQueryInfoKey has lpcSubKeys and lpcValues parameters which according to MSDN are,
	 * "A pointer to a variable that receives the number of subkeys that are contained by the specified key." and
	 * "A pointer to a variable that receives the number of values that are associated with the key.".
	 *
	 * RegEnumKey's MSDN docs say, "To retrieve the index of the last subkey, use the RegQueryInfoKey function."
	 *
	 * Instead of using these parameters because it's unclear how to use them and
	 * because using them simply does not work. We're going to loop until we get ERROR_NO_MORE_ITEMS.
	 */ /* Go though all values for this location delete them. */ /* Go though all sub keys and delete them. */ /* Delete the key now that all of its sub keys and values have been deleted. */