-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathRegKey.cs
236 lines (199 loc) · 8.3 KB
/
RegKey.cs
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
// Copyright (c) 2015, Dijji, and released under Ms-PL. This can be found in the root of this distribution.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
namespace RepairTasks
{
// Where we put nasty PInvoke stuff for exporting and reimporting registry keys
class RegKey
{
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern uint RegOpenKeyEx(
UIntPtr hKey,
string subKey,
int ulOptions,
int samDesired,
out UIntPtr hkResult);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern int RegCloseKey(
UIntPtr hKey);
public static UIntPtr HKEY_LOCAL_MACHINE = new UIntPtr(0x80000002u);
public static int KEY_READ = 0x20019;
public static int KEY_ALL_ACCESS = 0xF003F;
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint RegSaveKey(UIntPtr hKey, string lpFile, IntPtr lpSecurityAttributes);
public static uint ExportRegKeys(Dictionary<string, string> dictRegBackups)
{
// Need to copy the keys so we can modify the collection
List<string> keys = new List<string>(dictRegBackups.Keys);
uint result;
foreach (string key in keys)
{
UIntPtr hKey = UIntPtr.Zero;
result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, out hKey);
if (result == 0)
{
string tempFile = Path.GetTempFileName();
dictRegBackups[key] = tempFile;
File.Delete(tempFile); // ensure no collisions
result = RegSaveKey(hKey, tempFile, IntPtr.Zero);
if (result == 1314) // ERROR_PRIVILEGE_NOT_HELD
{
EnableDisablePrivilege("SeBackupPrivilege", true); // throws on failure
File.Delete(tempFile); // clean up first attempt
result = RegSaveKey(hKey, tempFile, IntPtr.Zero);
}
RegCloseKey(hKey);
if (result != 0)
{
File.Delete(tempFile); // clean up
return result;
}
}
else
return result;
}
return 0;
}
[Flags]
public enum RegOption
{
NonVolatile = 0x0,
Volatile = 0x1,
CreateLink = 0x2,
BackupRestore = 0x4,
OpenLink = 0x8
}
[Flags]
public enum RegSAM
{
QueryValue = 0x0001,
SetValue = 0x0002,
CreateSubKey = 0x0004,
EnumerateSubKeys = 0x0008,
Notify = 0x0010,
CreateLink = 0x0020,
WOW64_32Key = 0x0200,
WOW64_64Key = 0x0100,
WOW64_Res = 0x0300,
Read = 0x00020019,
Write = 0x00020006,
Execute = 0x00020019,
AllAccess = 0x000f003f
}
public enum RegResult
{
CreatedNewKey = 0x00000001,
OpenedExistingKey = 0x00000002
}
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
[DllImport("advapi32.dll", SetLastError = true)]
static extern uint RegCreateKeyEx(
UIntPtr hKey,
string lpSubKey,
int Reserved,
string lpClass,
RegOption dwOptions,
RegSAM samDesired,
ref SECURITY_ATTRIBUTES lpSecurityAttributes,
out UIntPtr phkResult,
out RegResult lpdwDisposition);
[DllImport("advapi32.dll", SetLastError = true)]
static extern uint RegLoadKey(UIntPtr hKey, String lpSubKey, String lpFile);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint RegRestoreKey(UIntPtr hKey, string lpFile, uint dwFlags);
public static uint RestoreRegKeys(Dictionary<string, string> dictRegBackups)
{
uint error = 0;
foreach (string key in dictRegBackups.Keys)
{
string backupFile = dictRegBackups[key];
string parentKey = Path.GetDirectoryName(key);
string childKey = Path.GetFileName(key);
uint result;
if (backupFile != null)
{
UIntPtr hKey = UIntPtr.Zero;
SECURITY_ATTRIBUTES sec = new SECURITY_ATTRIBUTES { nLength = 0, bInheritHandle = 0 };
RegResult disp;
result = RegCreateKeyEx(HKEY_LOCAL_MACHINE, key, 0, null, RegOption.BackupRestore, RegSAM.AllAccess, ref sec, out hKey, out disp);
if (result == 0)
{
result = RegRestoreKey(hKey, backupFile, 0);
System.Diagnostics.Trace.WriteLine(String.Format("RegRestoreKey returned {0}", result));
if (result == 1314) // ERROR_PRIVILEGE_NOT_HELD
{
EnableDisablePrivilege("SeRestorePrivilege", true); // throws on failure
result = RegRestoreKey(hKey, backupFile, 0);
System.Diagnostics.Trace.WriteLine(String.Format("RegRestoreKey #2 returned {0}", result));
}
RegCloseKey(hKey);
if (result != 0)
error = result;
}
else
error = result;
}
}
return error;
}
[StructLayout(LayoutKind.Sequential)]
public struct LUID
{
public uint LowPart;
public int HighPart;
}
[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_PRIVILEGES
{
public UInt32 PrivilegeCount;
public LUID Luid;
public UInt32 Attributes;
}
[DllImport("advapi32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, TokenAccessLevels DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, [MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges,
ref TOKEN_PRIVILEGES NewState, uint BufferLength, out TOKEN_PRIVILEGES PreviousState, out uint ReturnLength);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, out LUID lpLuid);
private static void EnableDisablePrivilege(string PrivilegeName, bool EnableDisable)
{
var htok = IntPtr.Zero;
if (!OpenProcessToken(Process.GetCurrentProcess().Handle, TokenAccessLevels.AdjustPrivileges | TokenAccessLevels.Query, out htok))
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
return;
}
var tkp = new TOKEN_PRIVILEGES { PrivilegeCount = 1 };
LUID luid;
if (!LookupPrivilegeValue(null, PrivilegeName, out luid))
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
return;
}
tkp.Luid = luid;
tkp.Attributes = (uint)(EnableDisable ? 2 : 0);
TOKEN_PRIVILEGES prv;
uint rb;
if (!AdjustTokenPrivileges(htok, false, ref tkp, 256, out prv, out rb))
{
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
return;
}
}
}
}