-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSysRestore.c
191 lines (156 loc) · 4.59 KB
/
SysRestore.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/*
* SysRestore plug-in for NSIS
*
* Written by Jason Ross aka JasonFriday13 on the forums.
*
* SysRestore.c
*/
/* Include the windows.h file, and the NSIS plugin header. */
#include <windows.h>
#include <srrestoreptapi.h>
#include "nsis\pluginapi.h" /* This means NSIS 2.42 or higher is required. */
/* Handle for the plugin. */
HANDLE hInstance;
/* Variables for the System Restore API */
PRESTOREPOINTINFO pRestPtInfo;
STATEMGRSTATUS SMgrStatus;
INT64 SequenceNumber = 0;
/* Internal variables. */
BOOL RestorePointStarted = FALSE, Initialized = FALSE;
void Destroy(void)
{
if (pRestPtInfo) GlobalFree(pRestPtInfo);
}
/* Our callback function so that our dll stays loaded. */
UINT_PTR __cdecl NSISPluginCallback(enum NSPIM Event)
{
if (Event == NSPIM_GUIUNLOAD)
Destroy();
return 0;
}
void Initialize(extra_parameters* xp)
{
if (!Initialized)
{
xp->RegisterPluginCallback(hInstance, NSISPluginCallback);
Initialized = TRUE;
}
}
/* This function is common to all functions. To reduce size,
having one copy instead of two saves space (I think). */
int SetRestorePoint(void)
{
TCHAR *pTemp;
pTemp = GlobalAlloc(GPTR, sizeof(TCHAR) * 64);
SRSetRestorePoint(pRestPtInfo, &SMgrStatus);
SequenceNumber = SMgrStatus.llSequenceNumber;
wsprintf(pTemp, TEXT("%u"), SMgrStatus.nStatus);
pushstring(pTemp);
GlobalFree(pTemp);
return SMgrStatus.nStatus;
}
/* These functions must be internal to the dll,
because they use a global variable. It does
not work if these functions are exported. */
int Begin(BOOL Uninstaller)
{
SecureZeroMemory(pRestPtInfo, sizeof(RESTOREPOINTINFO));
SecureZeroMemory(&SMgrStatus, sizeof(STATEMGRSTATUS));
/* Initialize the RESTOREPOINTINFO structure. */
pRestPtInfo->dwEventType = BEGIN_NESTED_SYSTEM_CHANGE;
/* Notify the system that changes are about to be made.
An application is to be installed (or uninstalled). */
if (Uninstaller)
pRestPtInfo->dwRestorePtType = APPLICATION_UNINSTALL;
else
pRestPtInfo->dwRestorePtType = APPLICATION_INSTALL;
/* Set RestPtInfo.llSequenceNumber. */
pRestPtInfo->llSequenceNumber = 0;
/* String to be displayed by System Restore for this restore point. */
popstring(pRestPtInfo->szDescription);
/* Notify the system that changes are to be made and that
the beginning of the restore point should be marked. */
return SetRestorePoint();
}
int Finish(void)
{
/* Re-initialize the RESTOREPOINTINFO structure to notify the
system that the operation is finished. */
pRestPtInfo->dwEventType = END_NESTED_SYSTEM_CHANGE;
/* End the system change by returning the sequence number
received from the first call to SRSetRestorePoint. */
pRestPtInfo->llSequenceNumber = SequenceNumber;
/* Notify the system that the operation is done and that this
is the end of the restore point. */
return SetRestorePoint();
}
int Remove(void)
{
int result;
result = SRRemoveRestorePoint((DWORD)SequenceNumber);
if (result == ERROR_SUCCESS)
return 1;
else
return 0;
}
__declspec(dllexport) void StartRestorePoint(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop, extra_parameters* xp)
{
EXDLL_INIT();
Initialize(xp);
/* This is to prevent multiple calls to SRSetRestorePoint. */
if (!RestorePointStarted)
{
if (Begin(FALSE) == ERROR_SUCCESS)
RestorePointStarted = TRUE;
}
else
pushint(1);
}
__declspec(dllexport) void StartUnRestorePoint(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop, extra_parameters* xp)
{
EXDLL_INIT();
Initialize(xp);
/* This is to prevent multiple calls to SRSetRestorePoint. */
if (!RestorePointStarted)
{
if (Begin(TRUE) == ERROR_SUCCESS)
RestorePointStarted = TRUE;
}
else
pushint(1);
}
__declspec(dllexport) void FinishRestorePoint(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop, extra_parameters* xp)
{
EXDLL_INIT();
Initialize(xp);
/* This is to prevent multiple calls to SRSetRestorePoint. */
if (RestorePointStarted)
{
if (Finish() == ERROR_SUCCESS)
RestorePointStarted = FALSE;
}
else
pushint(2);
}
void __declspec(dllexport) RemoveRestorePoint(HWND hwndParent, int string_size, TCHAR *variables, stack_t **stacktop, extra_parameters* xp)
{
EXDLL_INIT();
Initialize(xp);
/* This is to prevent multiple calls to SRSetRestorePoint. */
if (SequenceNumber)
{
if (Remove())
SequenceNumber = 0;
}
else
pushint(3);
}
BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
hInstance = hInst;
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
pRestPtInfo = GlobalAlloc(GPTR, sizeof(RESTOREPOINTINFO));
if (ul_reason_for_call == DLL_PROCESS_DETACH)
Destroy();
return TRUE;
}