You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by ar...@apache.org on 2010/11/18 15:22:02 UTC

svn commit: r1036462 - in /incubator/vcl/trunk/managementnode/lib/VCL/Module/OS: Linux.pm Windows.pm

Author: arkurth
Date: Thu Nov 18 14:22:02 2010
New Revision: 1036462

URL: http://svn.apache.org/viewvc?rev=1036462&view=rev
Log:
VCL-416
Added Windows.pm::fix_default_profile subroutine.  It loads the default user profile's ntuser.dat file into the registry, corrects known problems, and unloads the hive.  This is still being tested and isn't currently being called.  Also added reg_export, reg_load, and reg_unload subroutines which are called by fix_default_profile.

VCL-221
Added call to set_vcld_post_load_status at the end of the post_load subroutines in Windows.pm and Linux.pm to ensure that the status gets set in currentimage.txt, preventing post_load from being called more than once.

Other
Updated Windows.pm::format_path_unix to convert Windows-style variables (%x%)to Unix ($x).

Updated Linux.pm::get_available_space.  It was calculating the "Free" space instead of "Available".  Added get_total_space subroutine.  Updated get_file_size to calculate the size of a directory if a directory path argument is passed.

Modified:
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
    incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm?rev=1036462&r1=1036461&r2=1036462&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Thu Nov 18 14:22:02 2010
@@ -267,7 +267,10 @@ sub post_load {
 	
 	# Attempt to generate ifcfg-eth* files and ifup any interfaces which the file does not exist
 	$self->activate_interfaces();
-
+	
+	# Add a line to currentimage.txt indicating post_load has run
+	$self->set_vcld_post_load_status();
+	
 	return 1;
 
 } ## end sub post_load
@@ -1612,7 +1615,7 @@ sub get_file_contents {
 
 =head2 get_available_space
 
- Parameters  : none
+ Parameters  : $path
  Returns     : If successful: integer
                If failed: undefined
  Description : Returns the bytes available in the path specified by the
@@ -1662,19 +1665,88 @@ sub get_available_space {
 	}
 	
 	# Extract the blocks free value
-	my ($blocks_free) = $output_string =~ /Blocks:[^\n]*Free: (\d+)/;
-	if (!$blocks_free) {
-		notify($ERRORS{'WARNING'}, 0, "unable to locate blocks free value in stat output:\ncommand: $command\noutput:\n" . join("\n", @$output));
+	my ($blocks_available) = $output_string =~ /Blocks:[^\n]*Available: (\d+)/;
+	if (!defined($blocks_available)) {
+		notify($ERRORS{'WARNING'}, 0, "unable to locate blocks available value in stat output:\ncommand: $command\noutput:\n" . join("\n", @$output));
+		return;
+	}
+	
+	# Calculate the bytes available
+	my $bytes_available = ($block_size * $blocks_available);
+	my $mb_available = format_number(($bytes_available / 1024 / 1024), 2);
+	my $gb_available = format_number(($bytes_available / 1024 / 1024 / 1024), 1);
+	
+	notify($ERRORS{'DEBUG'}, 0, "bytes available in '$path' on $computer_short_name: " . format_number($bytes_available) . " bytes ($mb_available MB, $gb_available GB)");
+	return $bytes_available;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_total_space
+
+ Parameters  : $path
+ Returns     : If successful: integer
+               If failed: undefined
+ Description : Returns the total size in bytes of the volume where the path
+					resides specified by the argument. Undefined is returned if an
+					error occurred.
+
+=cut
+
+sub get_total_space {
+	my $self = shift;
+	if (ref($self) !~ /module/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+	
+	# Get the path argument
+	my $path = shift;
+	if (!$path) {
+		notify($ERRORS{'WARNING'}, 0, "path argument was not specified");
+		return;
+	}
+	
+	my $computer_short_name = $self->data->get_computer_short_name();
+	
+	# Run stat -f specifying the path as an argument
+	# Don't use df because you can't specify a path under ESX and parsing would be difficult
+	my $command = "stat -f \"$path\"";
+	my ($exit_status, $output) = $self->execute($command);
+	if (!defined($output)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to run command to determine available space on $computer_short_name:\ncommand: $command\noutput:\n" . join("\n", @$output));
+		return;
+	}
+	elsif (grep(/^stat: /i, @$output)) {
+		notify($ERRORS{'WARNING'}, 0, "error occurred running command to determine available space on $computer_short_name\ncommand: $command\noutput:\n" . join("\n", @$output));
+		return;
+	}
+	
+	# Create an output string from the array of lines for easier regex parsing
+	my $output_string = join("\n", @$output);
+	
+	# Extract the block size value
+	# Search case sensitive for 'Block size:' because the line may also contain "Fundamental block size:"
+	my ($block_size) = $output_string =~ /Block size: (\d+)/;
+	if (!$block_size) {
+		notify($ERRORS{'WARNING'}, 0, "unable to locate 'Block size:' value in stat output:\ncommand: $command\noutput:\n" . join("\n", @$output));
+		return;
+	}
+	
+	# Extract the blocks total value
+	my ($blocks_total) = $output_string =~ /Blocks:[^\n]*Total: (\d+)/;
+	if (!defined($blocks_total)) {
+		notify($ERRORS{'WARNING'}, 0, "unable to locate blocks total value in stat output:\ncommand: $command\noutput:\n" . join("\n", @$output));
 		return;
 	}
 	
 	# Calculate the bytes free
-	my $bytes_free = ($block_size * $blocks_free);
-	my $mb_free = format_number(($bytes_free / 1024 / 1024), 2);
-	my $gb_free = format_number(($bytes_free / 1024 / 1024 / 1024), 1);
+	my $bytes_total = ($block_size * $blocks_total);
+	my $mb_total = format_number(($bytes_total / 1024 / 1024), 2);
+	my $gb_total = format_number(($bytes_total / 1024 / 1024 / 1024), 1);
 	
-	notify($ERRORS{'DEBUG'}, 0, "bytes free in '$path' on $computer_short_name: " . format_number($bytes_free) . " bytes ($mb_free MB, $gb_free GB)");
-	return $bytes_free;
+	notify($ERRORS{'DEBUG'}, 0, "total bytes of volume where '$path' resides on $computer_short_name: " . format_number($bytes_total) . " bytes ($mb_total MB, $gb_total GB)");
+	return $bytes_total;
 }
 
 #/////////////////////////////////////////////////////////////////////////////
@@ -1920,10 +1992,30 @@ sub get_file_size {
 			$total_bytes_used += ($file_blocks * $block_size);
 			$total_bytes_allocated += $file_bytes;
 		}
+		elsif ($type =~ /directory/) {
+			$total_bytes_used += ($file_blocks * $block_size);
+			$total_bytes_allocated += $file_bytes;
+			
+			$path =~ s/[\\\/\*]+$//g;
+			notify($ERRORS{'DEBUG'}, 0, "recursively retrieving size of files under directory: '$path'");
+			my ($subdirectory_bytes_used, $subdirectory_bytes_allocated) = $self->get_file_size("$path/*");
+			$total_bytes_used += $subdirectory_bytes_used;
+			$total_bytes_allocated += $subdirectory_bytes_allocated;
+		}
+	}
+	
+	if ((caller(1))[3] !~ /get_file_size/) {
+		notify($ERRORS{'DEBUG'}, 0, "size of '$file_path' on $computer_node_name:\n" .
+				 "used: " . get_file_size_info_string($total_bytes_used) . "\n" .
+				 "allocated: " . get_file_size_info_string($total_bytes_allocated));
 	}
 	
-	notify($ERRORS{'DEBUG'}, 0, "size of $file_path on $computer_node_name: " . format_number($total_bytes_used) . " bytes, (" . format_number($total_bytes_allocated) . " bytes allocated)");
-	return $total_bytes_used;
+	if (wantarray) {
+		return ($total_bytes_used, $total_bytes_allocated);
+	}
+	else {
+		return $total_bytes_used;
+	}
 }
 
 #/////////////////////////////////////////////////////////////////////////////

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm?rev=1036462&r1=1036461&r2=1036462&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Thu Nov 18 14:22:02 2010
@@ -773,6 +773,14 @@ sub post_load {
 		}
 	}
 
+=item *
+
+ Add a line to currentimage.txt indicating post_load has run
+
+=cut
+
+	$self->set_vcld_post_load_status();
+
 =back
 
 =cut
@@ -2312,7 +2320,7 @@ sub import_registry_string {
 
 	# Echo the registry string to a file on the node
 	my $echo_registry_command = "rm -f $temp_registry_file_path; /usr/bin/echo.exe -E \"$registry_string\" > " . $temp_registry_file_path;
-	my ($echo_registry_exit_status, $echo_registry_output) = run_ssh_command($computer_node_name, $management_node_keys, $echo_registry_command, '', '', 1);
+	my ($echo_registry_exit_status, $echo_registry_output) = run_ssh_command($computer_node_name, $management_node_keys, $echo_registry_command, '', '', 0);
 	if (defined($echo_registry_exit_status) && $echo_registry_exit_status == 0) {
 		notify($ERRORS{'DEBUG'}, 0, "registry string contents echoed to $temp_registry_file_path");
 	}
@@ -2427,7 +2435,7 @@ sub reg_query {
 	}
 	
 	# Run reg.exe QUERY
-	my ($exit_status, $output) = run_ssh_command($computer_node_name, $management_node_keys, $command, '', '', 1);
+	my ($exit_status, $output) = run_ssh_command($computer_node_name, $management_node_keys, $command, '', '', 0);
 	if (!defined($output)) {
 		notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to query registry key: $key_argument");
 		return;
@@ -2440,7 +2448,7 @@ sub reg_query {
 		return;
 	}
 	
-	notify($ERRORS{'DEBUG'}, 0, "reg.exe QUERY output:\n" . join("\n", @$output));
+	#notify($ERRORS{'DEBUG'}, 0, "reg.exe QUERY output:\n" . join("\n", @$output));
 	
 	# If value argument was specified, parse and return the data
 	if (defined($value_argument)) {
@@ -2464,9 +2472,6 @@ sub reg_query {
 		my $key;
 		for my $line (@$output) {
 			if ($line =~ /^HKEY/) {
-				## Don't add the key being queried to the result, only add subkeys
-				#next if ($line eq $key_argument);
-				
 				$key = $line;
 				$registry_hash{$key} = {};
 				next;
@@ -2696,17 +2701,178 @@ sub reg_import {
 	}
 	
 	# Run reg.exe IMPORT
-	my $import_registry_command .= $system32_path . "/reg.exe IMPORT $registry_file_path";
-	my ($import_registry_exit_status, $import_registry_output) = run_ssh_command($computer_node_name, $management_node_keys, $import_registry_command, '', '', 1);
-	if (defined($import_registry_exit_status) && $import_registry_exit_status == 0) {
+	my $command .= $system32_path . "/reg.exe IMPORT $registry_file_path";
+	my ($exit_status, $output) = run_ssh_command($computer_node_name, $management_node_keys, $command, '', '', 0);
+	if (!defined($output)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to import registry file: $registry_file_path");
+		return;
+	}
+	elsif (grep(/completed successfully/i, @$output)) {
 		notify($ERRORS{'DEBUG'}, 0, "imported registry file: $registry_file_path");
 	}
-	elsif ($import_registry_exit_status) {
-		notify($ERRORS{'WARNING'}, 0, "failed to import registry file: $registry_file_path, exit status: $import_registry_exit_status, output:\n@{$import_registry_output}");
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to import registry file: $registry_file_path, exit status: $exit_status, output:\n" . join("\n", @$output));
 		return;
 	}
+	
+	return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 reg_export
+
+ Parameters  :
+ Returns     :
+ Description :
+
+=cut
+
+sub reg_export {
+	my $self = shift;
+	if (ref($self) !~ /windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+
+	my $management_node_keys = $self->data->get_management_node_keys();
+	my $computer_node_name   = $self->data->get_computer_node_name();
+	my $system32_path        = $self->get_system32_path() || return;
+	
+	# Get the arguments
+	my $root_key = shift;
+	if (!$root_key) {
+		notify($ERRORS{'WARNING'}, 0, "registry root key was not passed correctly as an argument");
+		return;
+	}
+	
+	# Get the registry file path argument
+	my $registry_file_path = shift;
+	if (!defined($registry_file_path) || !$registry_file_path) {
+		notify($ERRORS{'WARNING'}, 0, "registry file path was not passed correctly as an argument");
+		return;
+	}
+	$registry_file_path = $self->format_path_unix($registry_file_path);
+	
+	# Escape backslashes in the root key
+	$root_key =~ s/\\+/\\\\/;
+	
+	# Run reg.exe EXPORT
+	my $command .= $system32_path . "/reg.exe EXPORT $root_key $registry_file_path /y";
+	my ($exit_status, $output) = run_ssh_command($computer_node_name, $management_node_keys, $command, '', '', 1);
+	if (!defined($output)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to export registry key $root_key to file: $registry_file_path");
+		return;
+	}
+	elsif (grep(/completed successfully/i, @$output)) {
+		notify($ERRORS{'DEBUG'}, 0, "exported registry key $root_key to file: $registry_file_path");
+	}
 	else {
-		notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to import registry file: $registry_file_path");
+		notify($ERRORS{'WARNING'}, 0, "failed to export registry key $root_key to file: $registry_file_path, exit status: $exit_status, output:\n" . join("\n", @$output));
+		return;
+	}
+	
+	return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 reg_load
+
+ Parameters  : $root_key, $hive_file_path
+ Returns     :
+ Description :
+
+=cut
+
+sub reg_load {
+	my $self = shift;
+	if (ref($self) !~ /windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+
+	my $management_node_keys = $self->data->get_management_node_keys();
+	my $computer_node_name   = $self->data->get_computer_node_name();
+	my $system32_path        = $self->get_system32_path() || return;
+	
+	# Get the arguments
+	my $root_key = shift;
+	if (!$root_key) {
+		notify($ERRORS{'WARNING'}, 0, "registry root key was not passed correctly as an argument");
+		return;
+	}
+	my $hive_file_path = shift;
+	if (!$hive_file_path) {
+		notify($ERRORS{'WARNING'}, 0, "registry hive file path was not passed correctly as an argument");
+		return;
+	}
+	$hive_file_path = $self->format_path_unix($hive_file_path);
+	
+	# Escape backslashes in the root key
+	$root_key =~ s/\\+/\\\\/;
+	
+	# Run reg.exe LOAD
+	my $command .= "$system32_path/reg.exe LOAD $root_key $hive_file_path";
+	my ($exit_status, $output) = run_ssh_command($computer_node_name, $management_node_keys, $command, '', '', 0);
+	if (!defined($output)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to load registry hive file '$hive_file_path' into key $root_key");
+		return;
+	}
+	elsif (grep(/completed successfully/i, @$output)) {
+		notify($ERRORS{'DEBUG'}, 0, "loaded registry hive file '$hive_file_path' into key $root_key");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to load registry hive file '$hive_file_path' into key $root_key, exit status: $exit_status, output:\n" . join("\n", @$output));
+		return;
+	}
+	
+	return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 reg_unload
+
+ Parameters  : $root_key
+ Returns     :
+ Description :
+
+=cut
+
+sub reg_unload {
+	my $self = shift;
+	if (ref($self) !~ /windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+
+	my $management_node_keys = $self->data->get_management_node_keys();
+	my $computer_node_name   = $self->data->get_computer_node_name();
+	my $system32_path        = $self->get_system32_path() || return;
+	
+	# Get the arguments
+	my $root_key = shift;
+	if (!$root_key) {
+		notify($ERRORS{'WARNING'}, 0, "registry root key was not passed correctly as an argument");
+		return;
+	}
+	
+	# Escape backslashes in the root key
+	$root_key =~ s/\\+/\\\\/;
+	
+	# Run reg.exe UNLOAD
+	my $command .= "$system32_path/reg.exe UNLOAD $root_key";
+	my ($exit_status, $output) = run_ssh_command($computer_node_name, $management_node_keys, $command, '', '', 0);
+	if (!defined($output)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to run SSH command to unload registry hive: $root_key");
+		return;
+	}
+	elsif (grep(/completed successfully/i, @$output)) {
+		notify($ERRORS{'DEBUG'}, 0, "unloaded registry hive key: $root_key");
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to unload registry hive: $root_key, exit status: $exit_status, output:\n" . join("\n", @$output));
 		return;
 	}
 	
@@ -3321,7 +3487,10 @@ sub shutdown {
 		$shutdown_command .= "$system32_path/netsh.exe interface ip set dnsservers name=\\\"$private_interface_name\\\" source=dhcp & ";
 		$shutdown_command .= "$system32_path/netsh.exe interface ip set address name=\\\"$public_interface_name\\\" source=dhcp & ";
 		$shutdown_command .= "$system32_path/netsh.exe interface ip set dnsservers name=\\\"$public_interface_name\\\" source=dhcp & ";
+		$shutdown_command .= "$system32_path/netsh.exe interface ip reset & ";
 		$shutdown_command .= "$system32_path/ipconfig.exe /release & ";
+		$shutdown_command .= "$system32_path/ipconfig.exe /flushdns & ";
+		$shutdown_command .= "$system32_path/arp.exe -d * & ";
 		$shutdown_command .= "$system32_path/route.exe DELETE 0.0.0.0 MASK 0.0.0.0 & ";
 	}
 	else {
@@ -4048,11 +4217,11 @@ sub disable_netbios {
 	for my $interface_key (@interface_keys) {
 		my $netbios_options = $interface_registry_data->{$interface_key}{NetbiosOptions};
 		
-		next if !defined($netbios_options);
-		notify($ERRORS{'DEBUG'}, 0, "$interface_key: NetbiosOptions = $netbios_options");
-		
-		if (!$self->reg_add($interface_key, 'NetbiosOptions', 'REG_DWORD', 2)) {
-			notify($ERRORS{'WARNING'}, 0, "failed to set NetbiosOptions = 2 under interface key: $interface_key");
+		if ($self->reg_add($interface_key, 'NetbiosOptions', 'REG_DWORD', 2)) {
+			notify($ERRORS{'OK'}, 0, "disabled Netbios for interface: $interface_key");
+		}
+		else {
+			notify($ERRORS{'WARNING'}, 0, "failed to disabled Netbios for interface: $interface_key");
 			return;
 		}
 	}
@@ -8012,15 +8181,15 @@ sub format_path_unix {
 		return;	
 	}
 	
-	# Replace all backslashes with forward slashes
-	$path =~ s/[\\]+/\//g;
-	
-	# Replace multiple forward slashes with a single forward slash
-	$path =~ s/\/+/\//g;
+	# Replace all forward slashes and backslashes with a single forward slash
+	$path =~ s/[\/\\]+/\//g;
 	
 	# Escape all spaces
 	$path =~ s/ /\\ /g;
 	
+	# Change %VARIABLE% to $VARIABLE
+	$path =~ s/\%(.+)\%/\$$1/g;
+	
 	#notify($ERRORS{'DEBUG'}, 0, "formatted path for Unix: $path");
 	return $path;
 }
@@ -9907,6 +10076,87 @@ sub disable_login_screensaver {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 fix_default_profile
+
+ Parameters  : none
+ Returns     : boolean
+ Description : Attempts to correct common problems with the default user
+               profile by loading the default user registry hive from the
+               ntuser.dat file into the registry, making changes, then unloading
+               the hive.
+
+=cut
+
+sub fix_default_profile {
+	my $self = shift;
+	if (ref($self) !~ /windows/i) {
+		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
+		return;
+	}
+	
+	my $computer_node_name   = $self->data->get_computer_node_name();
+	
+	my $root_key = 'HKEY_USERS\DEFAULT_USER_PROFILE';
+	my $profile_list_key = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList';
+	
+	# Determine the default user profile path
+	my $profile_list_registry_info = $self->reg_query($profile_list_key);
+	if (!$profile_list_registry_info) {
+		notify($ERRORS{'WARNING'}, 0, "failed to retrieve profile information from the registry on $computer_node_name");
+		return;
+	}
+	elsif (!$profile_list_registry_info->{$profile_list_key}) {
+		notify($ERRORS{'WARNING'}, 0, "unable to determine default profile path, '$profile_list_key' key does not exist in the registry data:\n" . format_data($profile_list_registry_info));
+		return;
+	}
+	
+	# The default profile path should either be stored in the 'Default' value or can be assembled from combining the 'ProfilesDirectory' and 'DefaultUserProfile' values
+	my $default_profile_path;
+	if ($profile_list_registry_info->{$profile_list_key}{Default}) {
+		$default_profile_path = $profile_list_registry_info->{$profile_list_key}{Default};
+	}
+	elsif ($profile_list_registry_info->{$profile_list_key}{ProfilesDirectory} && $profile_list_registry_info->{$profile_list_key}{DefaultUserProfile}) {
+		$default_profile_path = "$profile_list_registry_info->{$profile_list_key}{ProfilesDirectory}\\$profile_list_registry_info->{$profile_list_key}{DefaultUserProfile}";
+	}
+	else {
+		notify($ERRORS{'WARNING'}, 0, "failed to determine default profile path from the registry on $computer_node_name:\n" . format_data($profile_list_registry_info->{$profile_list_key}));
+		return;
+	}
+	notify($ERRORS{'DEBUG'}, 0, "determined default profile path from the registry on $computer_node_name: '$default_profile_path'");
+
+	# Load the default profile hive file into the registry
+	my $hive_file_path = "$default_profile_path\\ntuser.dat";
+	if (!$self->reg_load($root_key, $hive_file_path)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to load the default profile hive into the registry on $computer_node_name");
+		return;
+	}
+return;
+	# Fix registry values known to cause problems
+	# The "Shell Folders" key may contain paths pointing to a specific user's profile
+	# Any paths under "Shell Folders" can be deleted
+	my $registry_string .= <<EOF;
+Windows Registry Editor Version 5.00
+[-$root_key\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders]
+[$root_key\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders]
+EOF
+
+	# Import the string into the registry
+	if (!$self->import_registry_string($registry_string)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to fix problematic registry settings in the default profile");
+		return;
+	}
+	
+	# Unoad the default profile hive
+	if (!$self->reg_unload($root_key)) {
+		notify($ERRORS{'WARNING'}, 0, "failed to unload the default profile hive from the registry on $computer_node_name");
+		return;
+	}
+
+	return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 1;
 __END__