I developed a NDIS 6.x LWF kernel driver and wrapped it into an installer using NSIS 2.46. I found that after its installation, Windows will automatically create a system restore point named Device Driver Package Install: Nmap Project Network Service
.
However, in fact it turns out that this restore point created by Windows is not good. I tried rolling back to that restore point, and my software is still there, including the driver .sys
file and other modifications to the system (like creating an adapter such as Windows Loopback Adapter
).
This is understandable because my installer indeed does some modifications before installing the driver, while Windows only takes the snapshot right when the driver is being installed. So my changes prior to the driver installation is not included.
So I decided to create a restore point by myself (using SysRestore
provided by NSIS) before all actual installation steps of the installer.
And I want to disable Windows to automatically create the restore point for my driver. What's the best to do this? Thanks!
The SysRestore plug-in calls SRSetRestorePoint
with BEGIN_SYSTEM_CHANGE
but according to MSDN you can call it with BEGIN_NESTED_SYSTEM_CHANGE
to only create one restore point. I don't know if this just applies to a single process or if it also applies to any child process you might be using to install the driver but it is perhaps worth a try. The code might look something like this:
!define MAX_DESC 64
!define MAX_DESC_W 256
!define STATEMGRSTATUS i,l
!define RESTOREPOINTINFOA i,i,l,&m${MAX_DESC}
!define RESTOREPOINTINFOW i,i,l,&w${MAX_DESC_W}
!if "${NSIS_CHAR_SIZE}" <= 1
!define RESTOREPOINTINFO "${RESTOREPOINTINFOA}"
!else
!define RESTOREPOINTINFO "${RESTOREPOINTINFOW}"
!endif
!define BEGIN_NESTED_SYSTEM_CHANGE 102
!define END_NESTED_SYSTEM_CHANGE 103
!define DEVICE_DRIVER_INSTALL 10
Section
System::Call 'KERNEL32::LoadLibrary(t "$SysDir\SrClient.dll")'
Var /Global SRSTATUS
System::Call '*(${STATEMGRSTATUS})i.s'
Pop $SRSTATUS
System::Call '*(${RESTOREPOINTINFO})(${BEGIN_NESTED_SYSTEM_CHANGE},${DEVICE_DRIVER_INSTALL},0,&t${MAX_DESC} "Installed driver XYZ")i.r0'
System::Call 'SrClient::SRSetRestorePoint(ir0,i$SRSTATUS)i.r1'
IntCmpU $1 0 "" +2 +2
System::Call '*$SRSTATUS(${STATEMGRSTATUS})(0)' ; Make sure nStatus is ERROR_SUCCESS
System::Free $0
DetailPrint "SRSetRestorePoint(BEGIN_NESTED_SYSTEM_CHANGE) returned $1"
; TODO: Install driver here
System::Call '*$SRSTATUS(${STATEMGRSTATUS})(.r0,.r1)' ; Extract nStatus and llSequenceNumber
IntCmpU $0 0 "" norpt norpt ; Did the first call to SRSetRestorePoint succeed?
System::Call '*(${RESTOREPOINTINFO})(${END_NESTED_SYSTEM_CHANGE},${DEVICE_DRIVER_INSTALL},r1)i.r0'
System::Call 'SrClient::SRSetRestorePoint(ir0,i$SRSTATUS)i.r1'
System::Free $0
DetailPrint "SRSetRestorePoint(END_NESTED_SYSTEM_CHANGE) returned $1"
norpt:
System::Free $SRSTATUS
SectionEnd