Sign in to follow this  
Followers 0
wraithdu

System Restore

1 post in this topic

I was interested in creating a System Restore point and only found the WMI version, so I put this together. It works great for creating a restore point. However according to MSDN, you should be able to cancel a restore point (delete it) if you choose, such as a user cancelling an installation. I have not been able to get this to work (as noted in the example). The function returns successfully, but the restore point is not removed. It should be viable via either the SRSetRestorePoint() function (with correct structure values) or the SRRemoveRestorePoint() function; both fail. If anyone can figure this out, it would be great.

While working on this, it is noted in MSDN that CoInitializeEx() and CoInitializeSecurity() must be called prior to using the Restore Point functions. I noticed that they still work however without doing this (I assume AutoIt must call some form of them during its own initialization). But when the system restore removal functions didn't work right, I implemented MSDN's example of both CoInit functions. Well, that didn't work either, so I guess it was a wasted effort. I'm including them here since it was a lot of work and someone may find them useful.

System Restore ex -

#cs
Initial call to SRSetRestorePoint, llSequenceNumber = 0.  Subsequent calls this member must be set to the value returned
from the initial call.

dwEventType is set to BEGIN_SYSTEM_CHANGE when creating the restore point before any system changes.  After the changes
are complete, set dwEventType to END_SYSTEM_CHANGE.

To remove a restore point if the changes are cancelled, set dwRestorePtType to CANCELLED_OPERATION and dwEventType to
END_SYSTEM_CHANGE.
#ce

; dwEventType
Global Const $BEGIN_SYSTEM_CHANGE = 100
Global Const $END_SYSTEM_CHANGE = 101
Global Const $BEGIN_NESTED_SYSTEM_CHANGE = 102
Global Const $END_NESTED_SYSTEM_CHANGE = 103
; dwRestorePtType
Global Const $APPLICATION_INSTALL = 0
Global Const $APPLICATION_UNINSTALL = 1
Global Const $DEVICE_INSTALL = 10
Global Const $MODIFY_SETTINGS = 12
Global Const $CANCELLED_OPERATION = 13
; nStatus
Global Const $ERROR_SUCCESS = 0
Global Const $ERROR_BAD_ENVIRONMENT = 10 ; function called in Safe Mode
Global Const $ERROR_DISK_FULL = 112
Global Const $ERROR_FILE_EXISTS = 80 ; pending file-rename operations exist in Wininit.ini
Global Const $ERROR_INTERNAL_ERROR = 1359
Global Const $ERROR_INVALID_DATA = 13 ; invalid llSequenceNumber
Global Const $ERROR_SERVICE_DISABLED = 1058
Global Const $ERROR_TIMEOUT = 1460
; other
Global Const $MAX_DESC = 1024

Global $tagRESTOREPOINTINFO = "dword dwEventType;dword dwRestorePtType;int64 llSequenceNumber;char szDescription[" & $MAX_DESC & "]"
Global $tagSTATEMGRSTATUS = "uint nStatus;int64 llSequenceNumber"

Global $RPINFO = DllStructCreate($tagRESTOREPOINTINFO)
Global $SMSTATUS = DllStructCreate($tagSTATEMGRSTATUS)

$SR_DLL = DllOpen("SrClient.dll")
If $SR_DLL == -1 Then
    ConsoleWrite("DllOpen failed" & @CRLF)
    Exit
EndIf

DllStructSetData($RPINFO, "dwEventType", $BEGIN_SYSTEM_CHANGE)
DllStructSetData($RPINFO, "dwRestorePtType", $APPLICATION_INSTALL)
DllStructSetData($RPINFO, "llSequenceNumber", 0)
DllStructSetData($RPINFO, "szDescription", "Cancel Test Application2")


$ret = DllCall($SR_DLL, "int", "SRSetRestorePoint", "ptr", DllStructGetPtr($RPINFO), "ptr", DllStructGetPtr($SMSTATUS))
If @error Then
    ConsoleWrite("Error: " & @error & @CRLF)
    DllClose($SR_DLL)
    Exit
EndIf
ConsoleWrite("Return: " & $ret[0] & @CRLF)
ConsoleWrite("nStatus: " & DllStructGetData($SMSTATUS, "nStatus") & @CRLF)
ConsoleWrite("llSequenceNumber: " & DllStructGetData($SMSTATUS, "llSequenceNumber") & @CRLF)

; This next call is to signal the end of system changes.  It is not really required under normal
; circumstances.  However you're supposed to be able to cancel the Restore Point as shown below
; by setting $CANCELLED_OPERATION.  I haven't been able to make this work.
; Normally, omit that change, set $END_SYSTEM_CHANGE, and make the call to end the RP.

If $ret[0] == 1 And DllStructGetData($SMSTATUS, "nStatus") == 0 Then
    ConsoleWrite("Call success" & @CRLF)
    
    DllStructSetData($RPINFO, "dwEventType", $END_SYSTEM_CHANGE)
    ; === supposed to cancel Restore Point ===========================
    DllStructSetData($RPINFO, "dwRestorePtType", $CANCELLED_OPERATION)
    ; ================================================================
    DllStructSetData($RPINFO, "llSequenceNumber", DllStructGetData($SMSTATUS, "llSequenceNumber"))
    
    $ret = DllCall($SR_DLL, "int", "SRSetRestorePoint", "ptr", DllStructGetPtr($RPINFO), "ptr", DllStructGetPtr($SMSTATUS))
    If @error Then ConsoleWrite("Error: " & @error & @CRLF)
    ConsoleWrite("Return: " & $ret[0] & @CRLF)
    ConsoleWrite("nStatus: " & DllStructGetData($SMSTATUS, "nStatus") & @CRLF)
    ConsoleWrite("llSequenceNumber: " & DllStructGetData($SMSTATUS, "llSequenceNumber") & @CRLF)
EndIf

DllClose($SR_DLL)

Share this post


Link to post
Share on other sites



Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0