Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Creating System Restore Points using PInvoke

0.00/5 (No votes)
23 Jul 2009 1  
How to create system restore points for Windows in C# with PInvoke
Systemrestore.png

Introduction

System Restore is a component of Microsoft's Windows ME, Windows XP and Windows Vista operating systems that allows for the rolling back of system files, registry keys, installed programs, etc., to a previous state in the event of malfunctioning or failure.1

What System Restore Does

Every Windows owner knows that System Restore is great if your system has crashed and all you need to do is run your computer in safe mode, run system restore and hope that it works on the next reboot.

It will also:

  • Create restore points so the computer can be returned to its previous state
  • Save disk space by letting the user specify how much of the hard drive to allocate for restore points
  • Create a new restore point once a user has restored the system
  • Backup the registry, certain file extensions, the local user profile, and much more
  • Restore the system from safe mode or the Windows Recovery Environment in Vista

What System Restore Doesn't Do

  • The ability to disable system restore from the registry can allow viruses and Trojans to disable the user from being unable to get rid of the virus.  
  • System restore was introduced with Windows ME, but although the timing of it was a bit late, they did not implement it into Windows 2000 or Windows Server. However, there is software available to install it into operating systems without it.
  • System restore points are saved to a specific directory and Microsoft has prohibited any applications from modifying this directory. If a virus is on the computer and a restore point is created, then an anti virus program won't be able to remove it from the directory and it will reinfect the computer when the computer is restored. 
  • If you are planning on using system restore functions in Windows ME, please be warned that it doesn't work with Microsoft .NET Framework 3.0 or higher.
  • A system restore point will be automatically removed if there isn't enough disk space. If a problem arises, it could be too late for the user to restore the computer to a working state.
  • Changes to a different drive sometimes are not monitored, this can cause programs that are installed on different drives to not function properly after a restore.
  • System restore does not work on Windows Vista and 7 with FAT32 disks or drives smaller than 1GB.
  • With all of the flaws and limitations of system restore, it is a good idea to equip your software with some kind of internal backup database. This way if system restore isn't working properly, the user can use your software to do a restore.

About Restore Points

Restore points are created using a DLL named "srclient.dll". There are two ways of creating a restore point, either through WMI (Windows Management Instruments) or the API (Application Programming Interface). I am going to show you how to do it with the API because the WMI only works on XP and the WMI is frustrating.

How the Code Works

Diagram.png

Restore Point Info

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct RestorePointInfo
{
    public int dwEventType; 	// The type of event
    public int dwRestorePtType; 	// The type of restore point
    public Int64 llSequenceNumber; 	// The sequence number of the restore point
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MaxDescW + 1)] 
    public string szDescription; 	// The description to be displayed so 
				//the user can easily identify a restore point
} 
Starting a Restore Point

The RestorePointInfo structure must specify dwEventType, dwRestorePtType, and szDescription when starting a restore point. The llSequenceNumber needs to be set to 0.

Ending a Restore Point

If you are ending a restore point, the structure requires llSequenceNumber and dwEventType. If it is cancelling the call, it also requires dwRestorePtType.

State Manager Status

The STATEMGRSTATUS is used as an output when the SRSetRestorePoint function is called. The sequence number needs to be saved to a variable when starting a restore point so it can be used again when ending the restore point. If the function returns false, nStatus receives the error information. To get the exception from the error code, use throw new Win32Exception(STATEMGRSTATUS.nStatus);

[StructLayout(LayoutKind.Sequential)]
public struct STATEMGRSTATUS
{
    public int nStatus; 		// The status code
    public Int64 llSequenceNumber; 	// The sequence number of the restore point
}

Type of Restores

There are several different types of restore points that can be created. They are pretty straightforward... If you are installing an application, it would be ApplicationInstall, If you are running an application for the first time, it would be FirstRun... etc..., etc...

public enum RestoreType
{
    ApplicationInstall = 0, 	// Installing a new application
    ApplicationUninstall = 1, 	// An application has been uninstalled
    ModifySettings = 12, 		// An application has had features added or removed
    CancelledOperation = 13, 	// An application needs to delete 
				// the restore point it created
    Restore = 6, 			// System Restore
    Checkpoint = 7, 		// Checkpoint
    DeviceDriverInstall = 10, 	// Device driver has been installed
    FirstRun = 11, 		// Program used for 1st time 
    BackupRecovery = 14 		// Restoring a backup
} 

Type of Events

When beginning a restore point, the event should be set to BeginSystemChange and then vice versa. The BeginNestedSystemChange and EndNestedSystemChange are used only on Windows XP when using nested restore points. For more information, see this link.

public const Int16 BeginSystemChange = 100;
public const Int16 EndSystemChange = 101; 
public const Int16 BeginNestedSystemChange = 102;
public const Int16 EndNestedSystemChange = 103;

Function

[DllImport("srclient.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SRSetRestorePointW
	(ref RestorePointInfo pRestorePtSpec, out STATEMGRSTATUS pSMgrStatus);

Starting A Restore Point

  1. Initialize COM security in your application so it can allow NetworkService, LocalService, and System. (I couldn't find any information on exact privileges that need to be set)
  2. Make sure that the operating system the program is running on has the system restore function.
  3. Use the RestorePointInfo structure to specify the restore information. Set the event type to BeginSystemChange. Then, set dwRestorePtType to the type of restore point you want and set szDescription to the description.
  4. Call SRSetRestorePointW. Check that the function returned true, if not, it means it could be disabled or something is wrong with it.
  5. The sequence number is very important because it needs to be used when cancelling or ending the restore point.

A Note...

In between the beginning and ending of the system change, is when system restore will record everything that needs to be undone at the restore. This is when you should do the system changes.

Cancelling/Ending A Restore Point

  1. Only set the event type in RestorePointInfo to EndSystemChange if you are ending the restore point.
  2. If you are cancelling the restore point, then set the restore point type to CancelledOperation and leave the event type to EndSystemChange.
  3. Set the sequence number to the number that was given by STATEMGRSTATUS when you started the restore point.
  4. Call SRSetRestorePointW.
  5. If the function returns false, it means the sequence number could not be found or the OS doesn't support system restore.

Conclusion

I have included all of the code needed for creating restore points in the ZIP archive. Sorry that I didn't include any documentation on any other APIs or the WMI classes. If you want to find out more, please check out the MSDN. You can also find out more about system restore here.

References

  1. http://en.wikipedia.org/w/index.php?title=System_Restore&oldid=287193831

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here