1*c2c66affSColin Finck #include "DriverTester.h"
2*c2c66affSColin Finck 
3*c2c66affSColin Finck static BOOL
SetPrivilege(BOOL bSet)4*c2c66affSColin Finck SetPrivilege(BOOL bSet)
5*c2c66affSColin Finck {
6*c2c66affSColin Finck     TOKEN_PRIVILEGES tp;
7*c2c66affSColin Finck     HANDLE hToken;
8*c2c66affSColin Finck     LUID luid;
9*c2c66affSColin Finck 
10*c2c66affSColin Finck     if (!OpenProcessToken(GetCurrentProcess(),
11*c2c66affSColin Finck                           TOKEN_ADJUST_PRIVILEGES,
12*c2c66affSColin Finck                           &hToken))
13*c2c66affSColin Finck     {
14*c2c66affSColin Finck         return FALSE;
15*c2c66affSColin Finck     }
16*c2c66affSColin Finck 
17*c2c66affSColin Finck     if(!LookupPrivilegeValue(NULL,
18*c2c66affSColin Finck                              SE_LOAD_DRIVER_NAME,
19*c2c66affSColin Finck                              &luid))
20*c2c66affSColin Finck     {
21*c2c66affSColin Finck         CloseHandle(hToken);
22*c2c66affSColin Finck         return FALSE;
23*c2c66affSColin Finck     }
24*c2c66affSColin Finck 
25*c2c66affSColin Finck     tp.PrivilegeCount = 1;
26*c2c66affSColin Finck     tp.Privileges[0].Luid = luid;
27*c2c66affSColin Finck 
28*c2c66affSColin Finck     if (bSet)
29*c2c66affSColin Finck     {
30*c2c66affSColin Finck         tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
31*c2c66affSColin Finck     }
32*c2c66affSColin Finck     else
33*c2c66affSColin Finck     {
34*c2c66affSColin Finck         tp.Privileges[0].Attributes = 0;
35*c2c66affSColin Finck     }
36*c2c66affSColin Finck 
37*c2c66affSColin Finck     AdjustTokenPrivileges(hToken,
38*c2c66affSColin Finck                           FALSE,
39*c2c66affSColin Finck                           &tp,
40*c2c66affSColin Finck                           sizeof(TOKEN_PRIVILEGES),
41*c2c66affSColin Finck                           NULL,
42*c2c66affSColin Finck                           NULL);
43*c2c66affSColin Finck     if (GetLastError() != ERROR_SUCCESS)
44*c2c66affSColin Finck     {
45*c2c66affSColin Finck         CloseHandle(hToken);
46*c2c66affSColin Finck         return FALSE;
47*c2c66affSColin Finck     }
48*c2c66affSColin Finck 
49*c2c66affSColin Finck     CloseHandle(hToken);
50*c2c66affSColin Finck 
51*c2c66affSColin Finck     return TRUE;
52*c2c66affSColin Finck }
53*c2c66affSColin Finck 
54*c2c66affSColin Finck 
55*c2c66affSColin Finck BOOL
ConvertPath(LPCWSTR lpPath,LPWSTR lpDevice)56*c2c66affSColin Finck ConvertPath(LPCWSTR lpPath,
57*c2c66affSColin Finck             LPWSTR lpDevice)
58*c2c66affSColin Finck {
59*c2c66affSColin Finck     LPWSTR lpFullPath = NULL;
60*c2c66affSColin Finck     DWORD size;
61*c2c66affSColin Finck 
62*c2c66affSColin Finck     if (lpPath)
63*c2c66affSColin Finck     {
64*c2c66affSColin Finck         size = GetLongPathNameW(lpPath,
65*c2c66affSColin Finck                                 0,
66*c2c66affSColin Finck                                 0);
67*c2c66affSColin Finck         if (!size)
68*c2c66affSColin Finck             return FALSE;
69*c2c66affSColin Finck 
70*c2c66affSColin Finck         size = (size + 1) * sizeof(WCHAR);
71*c2c66affSColin Finck 
72*c2c66affSColin Finck         lpFullPath = HeapAlloc(GetProcessHeap(),
73*c2c66affSColin Finck                                0,
74*c2c66affSColin Finck                                size);
75*c2c66affSColin Finck         if (!lpFullPath)
76*c2c66affSColin Finck             return FALSE;
77*c2c66affSColin Finck 
78*c2c66affSColin Finck         if (GetLongPathNameW(lpPath,
79*c2c66affSColin Finck                              lpFullPath,
80*c2c66affSColin Finck                              size))
81*c2c66affSColin Finck         {
82*c2c66affSColin Finck             HANDLE hDevice;
83*c2c66affSColin Finck             POBJECT_NAME_INFORMATION pObjName;
84*c2c66affSColin Finck             NTSTATUS Status;
85*c2c66affSColin Finck             DWORD len;
86*c2c66affSColin Finck 
87*c2c66affSColin Finck             hDevice = CreateFileW(lpFullPath,
88*c2c66affSColin Finck                                   GENERIC_READ | GENERIC_WRITE,
89*c2c66affSColin Finck                                   0,
90*c2c66affSColin Finck                                   NULL,
91*c2c66affSColin Finck                                   OPEN_EXISTING,
92*c2c66affSColin Finck                                   FILE_ATTRIBUTE_NORMAL,
93*c2c66affSColin Finck                                   NULL);
94*c2c66affSColin Finck 
95*c2c66affSColin Finck             HeapFree(GetProcessHeap(), 0, lpFullPath);
96*c2c66affSColin Finck 
97*c2c66affSColin Finck             if(hDevice == INVALID_HANDLE_VALUE)
98*c2c66affSColin Finck             {
99*c2c66affSColin Finck                 wprintf(L"[%x] Failed to open %s\n", GetLastError(), DRIVER_NAME);
100*c2c66affSColin Finck                 return FALSE;
101*c2c66affSColin Finck             }
102*c2c66affSColin Finck 
103*c2c66affSColin Finck             size = MAX_PATH * sizeof(WCHAR);
104*c2c66affSColin Finck             pObjName = HeapAlloc(GetProcessHeap(), 0, size);
105*c2c66affSColin Finck             if (!pObjName)
106*c2c66affSColin Finck                 return FALSE;
107*c2c66affSColin Finck 
108*c2c66affSColin Finck             Status = NtQueryObject(hDevice,
109*c2c66affSColin Finck                                    ObjectNameInformation,
110*c2c66affSColin Finck                                    pObjName,
111*c2c66affSColin Finck                                    size,
112*c2c66affSColin Finck                                    &size);
113*c2c66affSColin Finck             if (Status == STATUS_SUCCESS)
114*c2c66affSColin Finck             {
115*c2c66affSColin Finck                 len = pObjName->Name.Length / sizeof(WCHAR);
116*c2c66affSColin Finck                 wcsncpy(lpDevice, pObjName->Name.Buffer, len);
117*c2c66affSColin Finck                 lpDevice[len] = UNICODE_NULL;
118*c2c66affSColin Finck 
119*c2c66affSColin Finck                 HeapFree(GetProcessHeap(), 0, pObjName);
120*c2c66affSColin Finck 
121*c2c66affSColin Finck                 return TRUE;
122*c2c66affSColin Finck             }
123*c2c66affSColin Finck 
124*c2c66affSColin Finck             HeapFree(GetProcessHeap(), 0, pObjName);
125*c2c66affSColin Finck         }
126*c2c66affSColin Finck     }
127*c2c66affSColin Finck 
128*c2c66affSColin Finck     return FALSE;
129*c2c66affSColin Finck }
130*c2c66affSColin Finck 
131*c2c66affSColin Finck 
132*c2c66affSColin Finck BOOL
NtStartDriver(LPCWSTR lpService)133*c2c66affSColin Finck NtStartDriver(LPCWSTR lpService)
134*c2c66affSColin Finck {
135*c2c66affSColin Finck     WCHAR szDriverPath[MAX_PATH];
136*c2c66affSColin Finck     UNICODE_STRING DriverPath;
137*c2c66affSColin Finck     NTSTATUS Status = -1;
138*c2c66affSColin Finck 
139*c2c66affSColin Finck     wcscpy(szDriverPath,
140*c2c66affSColin Finck            L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
141*c2c66affSColin Finck     wcscat(szDriverPath,
142*c2c66affSColin Finck            lpService);
143*c2c66affSColin Finck 
144*c2c66affSColin Finck     RtlInitUnicodeString(&DriverPath,
145*c2c66affSColin Finck                          szDriverPath);
146*c2c66affSColin Finck 
147*c2c66affSColin Finck     if (SetPrivilege(TRUE))
148*c2c66affSColin Finck     {
149*c2c66affSColin Finck         Status = NtLoadDriver(&DriverPath);
150*c2c66affSColin Finck         if (Status != STATUS_SUCCESS)
151*c2c66affSColin Finck         {
152*c2c66affSColin Finck             DWORD err = RtlNtStatusToDosError(Status);
153*c2c66affSColin Finck             wprintf(L"NtUnloadDriver failed [%lu]\n", err);
154*c2c66affSColin Finck         }
155*c2c66affSColin Finck 
156*c2c66affSColin Finck         SetPrivilege(FALSE);
157*c2c66affSColin Finck     }
158*c2c66affSColin Finck 
159*c2c66affSColin Finck     return (Status == STATUS_SUCCESS);
160*c2c66affSColin Finck }
161*c2c66affSColin Finck 
162*c2c66affSColin Finck 
163*c2c66affSColin Finck BOOL
NtStopDriver(LPCWSTR lpService)164*c2c66affSColin Finck NtStopDriver(LPCWSTR lpService)
165*c2c66affSColin Finck {
166*c2c66affSColin Finck     WCHAR szDriverPath[MAX_PATH];
167*c2c66affSColin Finck     UNICODE_STRING DriverPath;
168*c2c66affSColin Finck     NTSTATUS Status = -1;
169*c2c66affSColin Finck 
170*c2c66affSColin Finck     wcscpy(szDriverPath,
171*c2c66affSColin Finck            L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
172*c2c66affSColin Finck     wcscat(szDriverPath,
173*c2c66affSColin Finck            lpService);
174*c2c66affSColin Finck 
175*c2c66affSColin Finck     RtlInitUnicodeString(&DriverPath,
176*c2c66affSColin Finck                          szDriverPath);
177*c2c66affSColin Finck 
178*c2c66affSColin Finck     if (SetPrivilege(TRUE))
179*c2c66affSColin Finck     {
180*c2c66affSColin Finck         Status = NtUnloadDriver(&DriverPath);
181*c2c66affSColin Finck         if (Status != STATUS_SUCCESS)
182*c2c66affSColin Finck         {
183*c2c66affSColin Finck             DWORD err = RtlNtStatusToDosError(Status);
184*c2c66affSColin Finck             wprintf(L"NtUnloadDriver failed [%lu]\n", err);
185*c2c66affSColin Finck         }
186*c2c66affSColin Finck 
187*c2c66affSColin Finck         SetPrivilege(FALSE);
188*c2c66affSColin Finck     }
189*c2c66affSColin Finck 
190*c2c66affSColin Finck     return (Status == STATUS_SUCCESS);
191*c2c66affSColin Finck }
192*c2c66affSColin Finck 
193*c2c66affSColin Finck 
194*c2c66affSColin Finck //
195*c2c66affSColin Finck // We shouldn't be able to call this from umode.
196*c2c66affSColin Finck // Returns true if
197*c2c66affSColin Finck //
198*c2c66affSColin Finck BOOL
LoadVia_SystemLoadGdiDriverInformation(LPWSTR lpDriverPath)199*c2c66affSColin Finck LoadVia_SystemLoadGdiDriverInformation(LPWSTR lpDriverPath)
200*c2c66affSColin Finck {
201*c2c66affSColin Finck     NTSTATUS Status;
202*c2c66affSColin Finck     SYSTEM_GDI_DRIVER_INFORMATION Buffer;
203*c2c66affSColin Finck     DWORD bufSize;
204*c2c66affSColin Finck 
205*c2c66affSColin Finck     bufSize = sizeof(SYSTEM_GDI_DRIVER_INFORMATION);
206*c2c66affSColin Finck 
207*c2c66affSColin Finck     ZeroMemory(&Buffer, bufSize);
208*c2c66affSColin Finck     RtlInitUnicodeString(&Buffer.DriverName, lpDriverPath);
209*c2c66affSColin Finck 
210*c2c66affSColin Finck     if (SetPrivilege(TRUE))
211*c2c66affSColin Finck     {
212*c2c66affSColin Finck         Status = NtSetSystemInformation(SystemLoadGdiDriverInformation,
213*c2c66affSColin Finck                                         &Buffer,
214*c2c66affSColin Finck                                         bufSize);
215*c2c66affSColin Finck         if (Status == STATUS_PRIVILEGE_NOT_HELD)
216*c2c66affSColin Finck         {
217*c2c66affSColin Finck             wprintf(L"SystemLoadGdiDriverInformation can only be used in kmode.\n");
218*c2c66affSColin Finck         }
219*c2c66affSColin Finck         else if (Status == STATUS_SUCCESS)
220*c2c66affSColin Finck         {
221*c2c66affSColin Finck             wprintf(L"SystemLoadGdiDriverInformation incorrectly loaded the driver\n");
222*c2c66affSColin Finck             NtUnloadDriver(&Buffer.DriverName);
223*c2c66affSColin Finck 
224*c2c66affSColin Finck             return TRUE;
225*c2c66affSColin Finck         }
226*c2c66affSColin Finck         else
227*c2c66affSColin Finck         {
228*c2c66affSColin Finck             DWORD err = RtlNtStatusToDosError(Status);
229*c2c66affSColin Finck             wprintf(L"LoadVia_SystemLoadGdiDriverInformation failed [%lu]\n", err);
230*c2c66affSColin Finck         }
231*c2c66affSColin Finck 
232*c2c66affSColin Finck         SetPrivilege(FALSE);
233*c2c66affSColin Finck     }
234*c2c66affSColin Finck 
235*c2c66affSColin Finck     return FALSE;
236*c2c66affSColin Finck }
237*c2c66affSColin Finck 
238*c2c66affSColin Finck 
239*c2c66affSColin Finck BOOL
LoadVia_SystemExtendServiceTableInformation(LPWSTR lpDriverPath)240*c2c66affSColin Finck LoadVia_SystemExtendServiceTableInformation(LPWSTR lpDriverPath)
241*c2c66affSColin Finck {
242*c2c66affSColin Finck     NTSTATUS Status;
243*c2c66affSColin Finck     UNICODE_STRING Buffer;
244*c2c66affSColin Finck     DWORD bufSize;
245*c2c66affSColin Finck 
246*c2c66affSColin Finck     RtlInitUnicodeString(&Buffer, lpDriverPath);
247*c2c66affSColin Finck     bufSize = sizeof(UNICODE_STRING);
248*c2c66affSColin Finck 
249*c2c66affSColin Finck     if (SetPrivilege(TRUE))
250*c2c66affSColin Finck     {
251*c2c66affSColin Finck         Status = NtSetSystemInformation(SystemExtendServiceTableInformation,
252*c2c66affSColin Finck                                         &Buffer,
253*c2c66affSColin Finck                                         bufSize);
254*c2c66affSColin Finck         if (Status == STATUS_PRIVILEGE_NOT_HELD)
255*c2c66affSColin Finck         {
256*c2c66affSColin Finck             wprintf(L"SystemExtendServiceTableInformation can only be used in kmode.\n");
257*c2c66affSColin Finck         }
258*c2c66affSColin Finck         else if (Status == STATUS_SUCCESS)
259*c2c66affSColin Finck         {
260*c2c66affSColin Finck             wprintf(L"SystemExtendServiceTableInformation incorrectly loaded the driver\n");
261*c2c66affSColin Finck             NtUnloadDriver(&Buffer);
262*c2c66affSColin Finck 
263*c2c66affSColin Finck             return TRUE;
264*c2c66affSColin Finck         }
265*c2c66affSColin Finck         else
266*c2c66affSColin Finck         {
267*c2c66affSColin Finck             DWORD err = RtlNtStatusToDosError(Status);
268*c2c66affSColin Finck             wprintf(L"LoadVia_SystemExtendServiceTableInformation failed [%lu] - 0x%x\n", err, Status);
269*c2c66affSColin Finck         }
270*c2c66affSColin Finck 
271*c2c66affSColin Finck         SetPrivilege(FALSE);
272*c2c66affSColin Finck     }
273*c2c66affSColin Finck 
274*c2c66affSColin Finck     return FALSE;
275*c2c66affSColin Finck }
276*c2c66affSColin Finck 
277