xref: /aosp_15_r20/external/pciutils/lib/win32-kldbg.c (revision c2e0c6b56a71da9abe8df5c8348fb3eb5c2c9251)
1*c2e0c6b5SAndroid Build Coastguard Worker /*
2*c2e0c6b5SAndroid Build Coastguard Worker  *      The PCI Library -- PCI config space access using Kernel Local Debugging Driver
3*c2e0c6b5SAndroid Build Coastguard Worker  *
4*c2e0c6b5SAndroid Build Coastguard Worker  *      Copyright (c) 2022 Pali Rohár <[email protected]>
5*c2e0c6b5SAndroid Build Coastguard Worker  *
6*c2e0c6b5SAndroid Build Coastguard Worker  *	Can be freely distributed and used under the terms of the GNU GPL v2+.
7*c2e0c6b5SAndroid Build Coastguard Worker  *
8*c2e0c6b5SAndroid Build Coastguard Worker  *	SPDX-License-Identifier: GPL-2.0-or-later
9*c2e0c6b5SAndroid Build Coastguard Worker  */
10*c2e0c6b5SAndroid Build Coastguard Worker 
11*c2e0c6b5SAndroid Build Coastguard Worker #include <windows.h>
12*c2e0c6b5SAndroid Build Coastguard Worker #include <winioctl.h>
13*c2e0c6b5SAndroid Build Coastguard Worker 
14*c2e0c6b5SAndroid Build Coastguard Worker #include <stdio.h> /* for sprintf() */
15*c2e0c6b5SAndroid Build Coastguard Worker #include <string.h> /* for memset() and memcpy() */
16*c2e0c6b5SAndroid Build Coastguard Worker 
17*c2e0c6b5SAndroid Build Coastguard Worker #include "internal.h"
18*c2e0c6b5SAndroid Build Coastguard Worker #include "win32-helpers.h"
19*c2e0c6b5SAndroid Build Coastguard Worker 
20*c2e0c6b5SAndroid Build Coastguard Worker #ifndef ERROR_NOT_FOUND
21*c2e0c6b5SAndroid Build Coastguard Worker #define ERROR_NOT_FOUND 1168
22*c2e0c6b5SAndroid Build Coastguard Worker #endif
23*c2e0c6b5SAndroid Build Coastguard Worker 
24*c2e0c6b5SAndroid Build Coastguard Worker #ifndef LOAD_LIBRARY_AS_IMAGE_RESOURCE
25*c2e0c6b5SAndroid Build Coastguard Worker #define LOAD_LIBRARY_AS_IMAGE_RESOURCE 0x20
26*c2e0c6b5SAndroid Build Coastguard Worker #endif
27*c2e0c6b5SAndroid Build Coastguard Worker #ifndef LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE
28*c2e0c6b5SAndroid Build Coastguard Worker #define LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE 0x40
29*c2e0c6b5SAndroid Build Coastguard Worker #endif
30*c2e0c6b5SAndroid Build Coastguard Worker 
31*c2e0c6b5SAndroid Build Coastguard Worker #ifndef IOCTL_KLDBG
32*c2e0c6b5SAndroid Build Coastguard Worker #define IOCTL_KLDBG CTL_CODE(FILE_DEVICE_UNKNOWN, 0x1, METHOD_NEITHER, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
33*c2e0c6b5SAndroid Build Coastguard Worker #endif
34*c2e0c6b5SAndroid Build Coastguard Worker 
35*c2e0c6b5SAndroid Build Coastguard Worker #ifndef BUS_DATA_TYPE
36*c2e0c6b5SAndroid Build Coastguard Worker #define BUS_DATA_TYPE LONG
37*c2e0c6b5SAndroid Build Coastguard Worker #endif
38*c2e0c6b5SAndroid Build Coastguard Worker #ifndef PCIConfiguration
39*c2e0c6b5SAndroid Build Coastguard Worker #define PCIConfiguration (BUS_DATA_TYPE)4
40*c2e0c6b5SAndroid Build Coastguard Worker #endif
41*c2e0c6b5SAndroid Build Coastguard Worker 
42*c2e0c6b5SAndroid Build Coastguard Worker #ifndef SYSDBG_COMMAND
43*c2e0c6b5SAndroid Build Coastguard Worker #define SYSDBG_COMMAND ULONG
44*c2e0c6b5SAndroid Build Coastguard Worker #endif
45*c2e0c6b5SAndroid Build Coastguard Worker #ifndef SysDbgReadBusData
46*c2e0c6b5SAndroid Build Coastguard Worker #define SysDbgReadBusData (SYSDBG_COMMAND)18
47*c2e0c6b5SAndroid Build Coastguard Worker #endif
48*c2e0c6b5SAndroid Build Coastguard Worker #ifndef SysDbgWriteBusData
49*c2e0c6b5SAndroid Build Coastguard Worker #define SysDbgWriteBusData (SYSDBG_COMMAND)19
50*c2e0c6b5SAndroid Build Coastguard Worker #endif
51*c2e0c6b5SAndroid Build Coastguard Worker 
52*c2e0c6b5SAndroid Build Coastguard Worker #ifndef SYSDBG_BUS_DATA
53*c2e0c6b5SAndroid Build Coastguard Worker typedef struct _SYSDBG_BUS_DATA {
54*c2e0c6b5SAndroid Build Coastguard Worker   ULONG Address;
55*c2e0c6b5SAndroid Build Coastguard Worker   PVOID Buffer;
56*c2e0c6b5SAndroid Build Coastguard Worker   ULONG Request;
57*c2e0c6b5SAndroid Build Coastguard Worker   BUS_DATA_TYPE BusDataType;
58*c2e0c6b5SAndroid Build Coastguard Worker   ULONG BusNumber;
59*c2e0c6b5SAndroid Build Coastguard Worker   ULONG SlotNumber;
60*c2e0c6b5SAndroid Build Coastguard Worker } SYSDBG_BUS_DATA, *PSYSDBG_BUS_DATA;
61*c2e0c6b5SAndroid Build Coastguard Worker #define SYSDBG_BUS_DATA SYSDBG_BUS_DATA
62*c2e0c6b5SAndroid Build Coastguard Worker #endif
63*c2e0c6b5SAndroid Build Coastguard Worker 
64*c2e0c6b5SAndroid Build Coastguard Worker #ifndef PCI_SEGMENT_BUS_NUMBER
65*c2e0c6b5SAndroid Build Coastguard Worker typedef struct _PCI_SEGMENT_BUS_NUMBER {
66*c2e0c6b5SAndroid Build Coastguard Worker   union {
67*c2e0c6b5SAndroid Build Coastguard Worker     struct {
68*c2e0c6b5SAndroid Build Coastguard Worker       ULONG BusNumber:8;
69*c2e0c6b5SAndroid Build Coastguard Worker       ULONG SegmentNumber:16;
70*c2e0c6b5SAndroid Build Coastguard Worker       ULONG Reserved:8;
71*c2e0c6b5SAndroid Build Coastguard Worker     } bits;
72*c2e0c6b5SAndroid Build Coastguard Worker     ULONG AsULONG;
73*c2e0c6b5SAndroid Build Coastguard Worker   } u;
74*c2e0c6b5SAndroid Build Coastguard Worker } PCI_SEGMENT_BUS_NUMBER, *PPCI_SEGMENT_BUS_NUMBER;
75*c2e0c6b5SAndroid Build Coastguard Worker #define PCI_SEGMENT_BUS_NUMBER PCI_SEGMENT_BUS_NUMBER
76*c2e0c6b5SAndroid Build Coastguard Worker #endif
77*c2e0c6b5SAndroid Build Coastguard Worker 
78*c2e0c6b5SAndroid Build Coastguard Worker #ifndef PCI_SLOT_NUMBER
79*c2e0c6b5SAndroid Build Coastguard Worker typedef struct _PCI_SLOT_NUMBER {
80*c2e0c6b5SAndroid Build Coastguard Worker   union {
81*c2e0c6b5SAndroid Build Coastguard Worker     struct {
82*c2e0c6b5SAndroid Build Coastguard Worker       ULONG DeviceNumber:5;
83*c2e0c6b5SAndroid Build Coastguard Worker       ULONG FunctionNumber:3;
84*c2e0c6b5SAndroid Build Coastguard Worker       ULONG Reserved:24;
85*c2e0c6b5SAndroid Build Coastguard Worker     } bits;
86*c2e0c6b5SAndroid Build Coastguard Worker     ULONG AsULONG;
87*c2e0c6b5SAndroid Build Coastguard Worker   } u;
88*c2e0c6b5SAndroid Build Coastguard Worker } PCI_SLOT_NUMBER, *PPCI_SLOT_NUMBER;
89*c2e0c6b5SAndroid Build Coastguard Worker #define PCI_SLOT_NUMBER PCI_SLOT_NUMBER
90*c2e0c6b5SAndroid Build Coastguard Worker #endif
91*c2e0c6b5SAndroid Build Coastguard Worker 
92*c2e0c6b5SAndroid Build Coastguard Worker #ifndef KLDBG
93*c2e0c6b5SAndroid Build Coastguard Worker typedef struct _KLDBG {
94*c2e0c6b5SAndroid Build Coastguard Worker   SYSDBG_COMMAND Command;
95*c2e0c6b5SAndroid Build Coastguard Worker   PVOID Buffer;
96*c2e0c6b5SAndroid Build Coastguard Worker   DWORD BufferLength;
97*c2e0c6b5SAndroid Build Coastguard Worker } KLDBG, *PKLDBG;
98*c2e0c6b5SAndroid Build Coastguard Worker #define KLDBG KLDBG
99*c2e0c6b5SAndroid Build Coastguard Worker #endif
100*c2e0c6b5SAndroid Build Coastguard Worker 
101*c2e0c6b5SAndroid Build Coastguard Worker static BOOL debug_privilege_enabled;
102*c2e0c6b5SAndroid Build Coastguard Worker static LUID luid_debug_privilege;
103*c2e0c6b5SAndroid Build Coastguard Worker static BOOL revert_only_privilege;
104*c2e0c6b5SAndroid Build Coastguard Worker static HANDLE revert_token;
105*c2e0c6b5SAndroid Build Coastguard Worker 
106*c2e0c6b5SAndroid Build Coastguard Worker static HANDLE kldbg_dev = INVALID_HANDLE_VALUE;
107*c2e0c6b5SAndroid Build Coastguard Worker 
108*c2e0c6b5SAndroid Build Coastguard Worker static BOOL
109*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_pci_bus_data(BOOL WriteBusData, USHORT SegmentNumber, BYTE BusNumber, BYTE DeviceNumber, BYTE FunctionNumber, USHORT Address, PVOID Buffer, ULONG BufferSize, LPDWORD Length);
110*c2e0c6b5SAndroid Build Coastguard Worker 
111*c2e0c6b5SAndroid Build Coastguard Worker static WORD
win32_get_current_process_machine(void)112*c2e0c6b5SAndroid Build Coastguard Worker win32_get_current_process_machine(void)
113*c2e0c6b5SAndroid Build Coastguard Worker {
114*c2e0c6b5SAndroid Build Coastguard Worker   IMAGE_DOS_HEADER *dos_header;
115*c2e0c6b5SAndroid Build Coastguard Worker   IMAGE_NT_HEADERS *nt_header;
116*c2e0c6b5SAndroid Build Coastguard Worker 
117*c2e0c6b5SAndroid Build Coastguard Worker   dos_header = (IMAGE_DOS_HEADER *)GetModuleHandle(NULL);
118*c2e0c6b5SAndroid Build Coastguard Worker   if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
119*c2e0c6b5SAndroid Build Coastguard Worker     return IMAGE_FILE_MACHINE_UNKNOWN;
120*c2e0c6b5SAndroid Build Coastguard Worker 
121*c2e0c6b5SAndroid Build Coastguard Worker   nt_header = (IMAGE_NT_HEADERS *)((BYTE *)dos_header + dos_header->e_lfanew);
122*c2e0c6b5SAndroid Build Coastguard Worker   if (nt_header->Signature != IMAGE_NT_SIGNATURE)
123*c2e0c6b5SAndroid Build Coastguard Worker     return IMAGE_FILE_MACHINE_UNKNOWN;
124*c2e0c6b5SAndroid Build Coastguard Worker 
125*c2e0c6b5SAndroid Build Coastguard Worker   return nt_header->FileHeader.Machine;
126*c2e0c6b5SAndroid Build Coastguard Worker }
127*c2e0c6b5SAndroid Build Coastguard Worker 
128*c2e0c6b5SAndroid Build Coastguard Worker static BOOL
win32_check_driver(BYTE * driver_data)129*c2e0c6b5SAndroid Build Coastguard Worker win32_check_driver(BYTE *driver_data)
130*c2e0c6b5SAndroid Build Coastguard Worker {
131*c2e0c6b5SAndroid Build Coastguard Worker   IMAGE_DOS_HEADER *dos_header;
132*c2e0c6b5SAndroid Build Coastguard Worker   IMAGE_NT_HEADERS *nt_headers;
133*c2e0c6b5SAndroid Build Coastguard Worker   WORD current_machine;
134*c2e0c6b5SAndroid Build Coastguard Worker 
135*c2e0c6b5SAndroid Build Coastguard Worker   current_machine = win32_get_current_process_machine();
136*c2e0c6b5SAndroid Build Coastguard Worker   if (current_machine == IMAGE_FILE_MACHINE_UNKNOWN)
137*c2e0c6b5SAndroid Build Coastguard Worker     return FALSE;
138*c2e0c6b5SAndroid Build Coastguard Worker 
139*c2e0c6b5SAndroid Build Coastguard Worker   dos_header = (IMAGE_DOS_HEADER *)driver_data;
140*c2e0c6b5SAndroid Build Coastguard Worker   if (dos_header->e_magic != IMAGE_DOS_SIGNATURE)
141*c2e0c6b5SAndroid Build Coastguard Worker     return FALSE;
142*c2e0c6b5SAndroid Build Coastguard Worker 
143*c2e0c6b5SAndroid Build Coastguard Worker   nt_headers = (IMAGE_NT_HEADERS *)((BYTE *)dos_header + dos_header->e_lfanew);
144*c2e0c6b5SAndroid Build Coastguard Worker   if (nt_headers->Signature != IMAGE_NT_SIGNATURE)
145*c2e0c6b5SAndroid Build Coastguard Worker     return FALSE;
146*c2e0c6b5SAndroid Build Coastguard Worker 
147*c2e0c6b5SAndroid Build Coastguard Worker   if (nt_headers->FileHeader.Machine != current_machine)
148*c2e0c6b5SAndroid Build Coastguard Worker     return FALSE;
149*c2e0c6b5SAndroid Build Coastguard Worker 
150*c2e0c6b5SAndroid Build Coastguard Worker   if (!(nt_headers->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE))
151*c2e0c6b5SAndroid Build Coastguard Worker     return FALSE;
152*c2e0c6b5SAndroid Build Coastguard Worker 
153*c2e0c6b5SAndroid Build Coastguard Worker #ifndef _WIN64
154*c2e0c6b5SAndroid Build Coastguard Worker   if (!(nt_headers->FileHeader.Characteristics & IMAGE_FILE_32BIT_MACHINE))
155*c2e0c6b5SAndroid Build Coastguard Worker     return FALSE;
156*c2e0c6b5SAndroid Build Coastguard Worker #endif
157*c2e0c6b5SAndroid Build Coastguard Worker 
158*c2e0c6b5SAndroid Build Coastguard Worker   /* IMAGE_NT_OPTIONAL_HDR_MAGIC is alias for the header magic used on the target compiler architecture. */
159*c2e0c6b5SAndroid Build Coastguard Worker   if (nt_headers->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
160*c2e0c6b5SAndroid Build Coastguard Worker     return FALSE;
161*c2e0c6b5SAndroid Build Coastguard Worker 
162*c2e0c6b5SAndroid Build Coastguard Worker   if (nt_headers->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_NATIVE)
163*c2e0c6b5SAndroid Build Coastguard Worker     return FALSE;
164*c2e0c6b5SAndroid Build Coastguard Worker 
165*c2e0c6b5SAndroid Build Coastguard Worker   return TRUE;
166*c2e0c6b5SAndroid Build Coastguard Worker }
167*c2e0c6b5SAndroid Build Coastguard Worker 
168*c2e0c6b5SAndroid Build Coastguard Worker static int
win32_kldbg_unpack_driver(struct pci_access * a,LPTSTR driver_path)169*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_unpack_driver(struct pci_access *a, LPTSTR driver_path)
170*c2e0c6b5SAndroid Build Coastguard Worker {
171*c2e0c6b5SAndroid Build Coastguard Worker   BOOL use_kd_exe = FALSE;
172*c2e0c6b5SAndroid Build Coastguard Worker   HMODULE exe_with_driver = NULL;
173*c2e0c6b5SAndroid Build Coastguard Worker   HRSRC driver_resource_info = NULL;
174*c2e0c6b5SAndroid Build Coastguard Worker   HGLOBAL driver_resource = NULL;
175*c2e0c6b5SAndroid Build Coastguard Worker   BYTE *driver_data = NULL;
176*c2e0c6b5SAndroid Build Coastguard Worker   DWORD driver_size = 0;
177*c2e0c6b5SAndroid Build Coastguard Worker   HANDLE driver_handle = INVALID_HANDLE_VALUE;
178*c2e0c6b5SAndroid Build Coastguard Worker   DWORD written = 0;
179*c2e0c6b5SAndroid Build Coastguard Worker   DWORD error = 0;
180*c2e0c6b5SAndroid Build Coastguard Worker   int ret = 0;
181*c2e0c6b5SAndroid Build Coastguard Worker 
182*c2e0c6b5SAndroid Build Coastguard Worker   /* Try to find and open windbg.exe or kd.exe file in PATH. */
183*c2e0c6b5SAndroid Build Coastguard Worker   exe_with_driver = LoadLibraryEx(TEXT("windbg.exe"), NULL, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
184*c2e0c6b5SAndroid Build Coastguard Worker   if (!exe_with_driver)
185*c2e0c6b5SAndroid Build Coastguard Worker     {
186*c2e0c6b5SAndroid Build Coastguard Worker       use_kd_exe = TRUE;
187*c2e0c6b5SAndroid Build Coastguard Worker       exe_with_driver = LoadLibraryEx(TEXT("kd.exe"), NULL, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
188*c2e0c6b5SAndroid Build Coastguard Worker     }
189*c2e0c6b5SAndroid Build Coastguard Worker   if (!exe_with_driver)
190*c2e0c6b5SAndroid Build Coastguard Worker     {
191*c2e0c6b5SAndroid Build Coastguard Worker       error = GetLastError();
192*c2e0c6b5SAndroid Build Coastguard Worker       if (error == ERROR_FILE_NOT_FOUND ||
193*c2e0c6b5SAndroid Build Coastguard Worker           error == ERROR_MOD_NOT_FOUND)
194*c2e0c6b5SAndroid Build Coastguard Worker         a->debug("Cannot find windbg.exe or kd.exe file in PATH");
195*c2e0c6b5SAndroid Build Coastguard Worker       else
196*c2e0c6b5SAndroid Build Coastguard Worker         a->debug("Cannot load %s file: %s.", use_kd_exe ? "kd.exe" : "windbg.exe", win32_strerror(error));
197*c2e0c6b5SAndroid Build Coastguard Worker       goto out;
198*c2e0c6b5SAndroid Build Coastguard Worker     }
199*c2e0c6b5SAndroid Build Coastguard Worker 
200*c2e0c6b5SAndroid Build Coastguard Worker   /* kldbgdrv.sys is embedded in windbg.exe/kd.exe as a resource with name id 0x7777 and type id 0x4444. */
201*c2e0c6b5SAndroid Build Coastguard Worker   driver_resource_info = FindResource(exe_with_driver, MAKEINTRESOURCE(0x7777), MAKEINTRESOURCE(0x4444));
202*c2e0c6b5SAndroid Build Coastguard Worker   if (!driver_resource_info)
203*c2e0c6b5SAndroid Build Coastguard Worker     {
204*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("Cannot find kldbgdrv.sys resource in %s file: %s.", use_kd_exe ? "kd.exe" : "windbg.exe", win32_strerror(GetLastError()));
205*c2e0c6b5SAndroid Build Coastguard Worker       goto out;
206*c2e0c6b5SAndroid Build Coastguard Worker     }
207*c2e0c6b5SAndroid Build Coastguard Worker 
208*c2e0c6b5SAndroid Build Coastguard Worker   driver_resource = LoadResource(exe_with_driver, driver_resource_info);
209*c2e0c6b5SAndroid Build Coastguard Worker   if (!driver_resource)
210*c2e0c6b5SAndroid Build Coastguard Worker     {
211*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("Cannot load kldbgdrv.sys resource from %s file: %s.", use_kd_exe ? "kd.exe" : "windbg.exe", win32_strerror(GetLastError()));
212*c2e0c6b5SAndroid Build Coastguard Worker       goto out;
213*c2e0c6b5SAndroid Build Coastguard Worker     }
214*c2e0c6b5SAndroid Build Coastguard Worker 
215*c2e0c6b5SAndroid Build Coastguard Worker   driver_size = SizeofResource(exe_with_driver, driver_resource_info);
216*c2e0c6b5SAndroid Build Coastguard Worker   if (!driver_size)
217*c2e0c6b5SAndroid Build Coastguard Worker     {
218*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("Cannot determinate size of kldbgdrv.sys resource from %s file: %s.", use_kd_exe ? "kd.exe" : "windbg.exe", win32_strerror(GetLastError()));
219*c2e0c6b5SAndroid Build Coastguard Worker       goto out;
220*c2e0c6b5SAndroid Build Coastguard Worker     }
221*c2e0c6b5SAndroid Build Coastguard Worker 
222*c2e0c6b5SAndroid Build Coastguard Worker   driver_data = LockResource(driver_resource);
223*c2e0c6b5SAndroid Build Coastguard Worker   if (!driver_data)
224*c2e0c6b5SAndroid Build Coastguard Worker     {
225*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("Cannot load kldbgdrv.sys resouce data from %s file: %s.", use_kd_exe ? "kd.exe" : "windbg.exe", win32_strerror(GetLastError()));
226*c2e0c6b5SAndroid Build Coastguard Worker       goto out;
227*c2e0c6b5SAndroid Build Coastguard Worker     }
228*c2e0c6b5SAndroid Build Coastguard Worker 
229*c2e0c6b5SAndroid Build Coastguard Worker   if (!win32_check_driver(driver_data))
230*c2e0c6b5SAndroid Build Coastguard Worker     {
231*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("Cannot use kldbgdrv.sys driver from %s file: Driver is from different architecture.", use_kd_exe ? "kd.exe" : "windbg.exe");
232*c2e0c6b5SAndroid Build Coastguard Worker       goto out;
233*c2e0c6b5SAndroid Build Coastguard Worker     }
234*c2e0c6b5SAndroid Build Coastguard Worker 
235*c2e0c6b5SAndroid Build Coastguard Worker   driver_handle = CreateFile(driver_path, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
236*c2e0c6b5SAndroid Build Coastguard Worker   if (driver_handle == INVALID_HANDLE_VALUE)
237*c2e0c6b5SAndroid Build Coastguard Worker     {
238*c2e0c6b5SAndroid Build Coastguard Worker       error = GetLastError();
239*c2e0c6b5SAndroid Build Coastguard Worker       if (error != ERROR_FILE_EXISTS)
240*c2e0c6b5SAndroid Build Coastguard Worker         {
241*c2e0c6b5SAndroid Build Coastguard Worker           a->debug("Cannot create kldbgdrv.sys driver file in system32 directory: %s.", win32_strerror(error));
242*c2e0c6b5SAndroid Build Coastguard Worker           goto out;
243*c2e0c6b5SAndroid Build Coastguard Worker         }
244*c2e0c6b5SAndroid Build Coastguard Worker       /* If driver file in system32 directory already exists then treat it as successfull unpack. */
245*c2e0c6b5SAndroid Build Coastguard Worker       ret = 1;
246*c2e0c6b5SAndroid Build Coastguard Worker       goto out;
247*c2e0c6b5SAndroid Build Coastguard Worker     }
248*c2e0c6b5SAndroid Build Coastguard Worker 
249*c2e0c6b5SAndroid Build Coastguard Worker   if (!WriteFile(driver_handle, driver_data, driver_size, &written, NULL) ||
250*c2e0c6b5SAndroid Build Coastguard Worker       written != driver_size)
251*c2e0c6b5SAndroid Build Coastguard Worker     {
252*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("Cannot store kldbgdrv.sys driver file to system32 directory: %s.", win32_strerror(GetLastError()));
253*c2e0c6b5SAndroid Build Coastguard Worker       /* On error, delete file from system32 directory to allow another unpack attempt. */
254*c2e0c6b5SAndroid Build Coastguard Worker       CloseHandle(driver_handle);
255*c2e0c6b5SAndroid Build Coastguard Worker       driver_handle = INVALID_HANDLE_VALUE;
256*c2e0c6b5SAndroid Build Coastguard Worker       DeleteFile(driver_path);
257*c2e0c6b5SAndroid Build Coastguard Worker       goto out;
258*c2e0c6b5SAndroid Build Coastguard Worker     }
259*c2e0c6b5SAndroid Build Coastguard Worker 
260*c2e0c6b5SAndroid Build Coastguard Worker   a->debug("Driver kldbgdrv.sys was successfully unpacked from %s and stored in system32 directory...", use_kd_exe ? "kd.exe" : "windbg.exe");
261*c2e0c6b5SAndroid Build Coastguard Worker   ret = 1;
262*c2e0c6b5SAndroid Build Coastguard Worker 
263*c2e0c6b5SAndroid Build Coastguard Worker out:
264*c2e0c6b5SAndroid Build Coastguard Worker   if (driver_handle != INVALID_HANDLE_VALUE)
265*c2e0c6b5SAndroid Build Coastguard Worker     CloseHandle(driver_handle);
266*c2e0c6b5SAndroid Build Coastguard Worker 
267*c2e0c6b5SAndroid Build Coastguard Worker   if (driver_resource)
268*c2e0c6b5SAndroid Build Coastguard Worker     FreeResource(driver_resource);
269*c2e0c6b5SAndroid Build Coastguard Worker 
270*c2e0c6b5SAndroid Build Coastguard Worker   if (exe_with_driver)
271*c2e0c6b5SAndroid Build Coastguard Worker     FreeLibrary(exe_with_driver);
272*c2e0c6b5SAndroid Build Coastguard Worker 
273*c2e0c6b5SAndroid Build Coastguard Worker   return ret;
274*c2e0c6b5SAndroid Build Coastguard Worker }
275*c2e0c6b5SAndroid Build Coastguard Worker 
276*c2e0c6b5SAndroid Build Coastguard Worker static int
win32_kldbg_register_driver(struct pci_access * a,SC_HANDLE manager,SC_HANDLE * service)277*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_register_driver(struct pci_access *a, SC_HANDLE manager, SC_HANDLE *service)
278*c2e0c6b5SAndroid Build Coastguard Worker {
279*c2e0c6b5SAndroid Build Coastguard Worker   UINT system32_len;
280*c2e0c6b5SAndroid Build Coastguard Worker   LPTSTR driver_path;
281*c2e0c6b5SAndroid Build Coastguard Worker   HANDLE driver_handle;
282*c2e0c6b5SAndroid Build Coastguard Worker 
283*c2e0c6b5SAndroid Build Coastguard Worker   /*
284*c2e0c6b5SAndroid Build Coastguard Worker    * COM library dbgeng.dll unpacks kldbg driver to file "\\system32\\kldbgdrv.sys"
285*c2e0c6b5SAndroid Build Coastguard Worker    * and register this driver with service name kldbgdrv. Implement same behavior.
286*c2e0c6b5SAndroid Build Coastguard Worker    * GetSystemDirectory() returns path to "\\system32" directory on all Windows versions.
287*c2e0c6b5SAndroid Build Coastguard Worker    */
288*c2e0c6b5SAndroid Build Coastguard Worker 
289*c2e0c6b5SAndroid Build Coastguard Worker   system32_len = GetSystemDirectory(NULL, 0); /* Returns number of TCHARs plus 1 for nul-term. */
290*c2e0c6b5SAndroid Build Coastguard Worker   if (!system32_len)
291*c2e0c6b5SAndroid Build Coastguard Worker     system32_len = sizeof("C:\\Windows\\System32");
292*c2e0c6b5SAndroid Build Coastguard Worker 
293*c2e0c6b5SAndroid Build Coastguard Worker   driver_path = pci_malloc(a, (system32_len + sizeof("\\kldbgdrv.sys")-1) * sizeof(TCHAR));
294*c2e0c6b5SAndroid Build Coastguard Worker 
295*c2e0c6b5SAndroid Build Coastguard Worker   system32_len = GetSystemDirectory(driver_path, system32_len); /* Now it returns number of TCHARs without nul-term. */
296*c2e0c6b5SAndroid Build Coastguard Worker   if (!system32_len)
297*c2e0c6b5SAndroid Build Coastguard Worker     {
298*c2e0c6b5SAndroid Build Coastguard Worker       system32_len = sizeof("C:\\Windows\\System32")-1;
299*c2e0c6b5SAndroid Build Coastguard Worker       memcpy(driver_path, TEXT("C:\\Windows\\System32"), system32_len);
300*c2e0c6b5SAndroid Build Coastguard Worker     }
301*c2e0c6b5SAndroid Build Coastguard Worker 
302*c2e0c6b5SAndroid Build Coastguard Worker   /* GetSystemDirectory returns path without backslash unless the system directory is the root directory. */
303*c2e0c6b5SAndroid Build Coastguard Worker   if (driver_path[system32_len-1] != '\\')
304*c2e0c6b5SAndroid Build Coastguard Worker     driver_path[system32_len++] = '\\';
305*c2e0c6b5SAndroid Build Coastguard Worker 
306*c2e0c6b5SAndroid Build Coastguard Worker   memcpy(driver_path + system32_len, TEXT("kldbgdrv.sys"), sizeof(TEXT("kldbgdrv.sys")));
307*c2e0c6b5SAndroid Build Coastguard Worker 
308*c2e0c6b5SAndroid Build Coastguard Worker   driver_handle = CreateFile(driver_path, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
309*c2e0c6b5SAndroid Build Coastguard Worker   if (driver_handle != INVALID_HANDLE_VALUE)
310*c2e0c6b5SAndroid Build Coastguard Worker     CloseHandle(driver_handle);
311*c2e0c6b5SAndroid Build Coastguard Worker   else if (GetLastError() == ERROR_FILE_NOT_FOUND)
312*c2e0c6b5SAndroid Build Coastguard Worker     {
313*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("Driver kldbgdrv.sys is missing, trying to unpack it from windbg.exe or kd.exe...");
314*c2e0c6b5SAndroid Build Coastguard Worker       if (!win32_kldbg_unpack_driver(a, driver_path))
315*c2e0c6b5SAndroid Build Coastguard Worker         {
316*c2e0c6b5SAndroid Build Coastguard Worker           pci_mfree(driver_path);
317*c2e0c6b5SAndroid Build Coastguard Worker           return 0;
318*c2e0c6b5SAndroid Build Coastguard Worker         }
319*c2e0c6b5SAndroid Build Coastguard Worker     }
320*c2e0c6b5SAndroid Build Coastguard Worker 
321*c2e0c6b5SAndroid Build Coastguard Worker   *service = CreateService(manager, TEXT("kldbgdrv"), TEXT("kldbgdrv"), SERVICE_START, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, driver_path, NULL, NULL, NULL, NULL, NULL);
322*c2e0c6b5SAndroid Build Coastguard Worker   if (!*service)
323*c2e0c6b5SAndroid Build Coastguard Worker     {
324*c2e0c6b5SAndroid Build Coastguard Worker       if (GetLastError() != ERROR_SERVICE_EXISTS)
325*c2e0c6b5SAndroid Build Coastguard Worker         {
326*c2e0c6b5SAndroid Build Coastguard Worker           a->debug("Cannot create kldbgdrv service: %s.", win32_strerror(GetLastError()));
327*c2e0c6b5SAndroid Build Coastguard Worker           pci_mfree(driver_path);
328*c2e0c6b5SAndroid Build Coastguard Worker           return 0;
329*c2e0c6b5SAndroid Build Coastguard Worker         }
330*c2e0c6b5SAndroid Build Coastguard Worker 
331*c2e0c6b5SAndroid Build Coastguard Worker       *service = OpenService(manager, TEXT("kldbgdrv"), SERVICE_START);
332*c2e0c6b5SAndroid Build Coastguard Worker       if (!*service)
333*c2e0c6b5SAndroid Build Coastguard Worker         {
334*c2e0c6b5SAndroid Build Coastguard Worker           a->debug("Cannot open kldbgdrv service: %s.", win32_strerror(GetLastError()));
335*c2e0c6b5SAndroid Build Coastguard Worker           pci_mfree(driver_path);
336*c2e0c6b5SAndroid Build Coastguard Worker           return 0;
337*c2e0c6b5SAndroid Build Coastguard Worker         }
338*c2e0c6b5SAndroid Build Coastguard Worker     }
339*c2e0c6b5SAndroid Build Coastguard Worker 
340*c2e0c6b5SAndroid Build Coastguard Worker   a->debug("Service kldbgdrv was successfully registered...");
341*c2e0c6b5SAndroid Build Coastguard Worker   pci_mfree(driver_path);
342*c2e0c6b5SAndroid Build Coastguard Worker   return 1;
343*c2e0c6b5SAndroid Build Coastguard Worker }
344*c2e0c6b5SAndroid Build Coastguard Worker 
345*c2e0c6b5SAndroid Build Coastguard Worker static int
win32_kldbg_start_driver(struct pci_access * a)346*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_start_driver(struct pci_access *a)
347*c2e0c6b5SAndroid Build Coastguard Worker {
348*c2e0c6b5SAndroid Build Coastguard Worker   SC_HANDLE manager = NULL;
349*c2e0c6b5SAndroid Build Coastguard Worker   SC_HANDLE service = NULL;
350*c2e0c6b5SAndroid Build Coastguard Worker   DWORD error = 0;
351*c2e0c6b5SAndroid Build Coastguard Worker   int ret = 0;
352*c2e0c6b5SAndroid Build Coastguard Worker 
353*c2e0c6b5SAndroid Build Coastguard Worker   manager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
354*c2e0c6b5SAndroid Build Coastguard Worker   if (!manager)
355*c2e0c6b5SAndroid Build Coastguard Worker     manager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
356*c2e0c6b5SAndroid Build Coastguard Worker   if (!manager)
357*c2e0c6b5SAndroid Build Coastguard Worker     {
358*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("Cannot open Service Manager: %s.", win32_strerror(GetLastError()));
359*c2e0c6b5SAndroid Build Coastguard Worker       return 0;
360*c2e0c6b5SAndroid Build Coastguard Worker     }
361*c2e0c6b5SAndroid Build Coastguard Worker 
362*c2e0c6b5SAndroid Build Coastguard Worker   service = OpenService(manager, TEXT("kldbgdrv"), SERVICE_START);
363*c2e0c6b5SAndroid Build Coastguard Worker   if (!service)
364*c2e0c6b5SAndroid Build Coastguard Worker     {
365*c2e0c6b5SAndroid Build Coastguard Worker       error = GetLastError();
366*c2e0c6b5SAndroid Build Coastguard Worker       if (error != ERROR_SERVICE_DOES_NOT_EXIST)
367*c2e0c6b5SAndroid Build Coastguard Worker         {
368*c2e0c6b5SAndroid Build Coastguard Worker           a->debug("Cannot open kldbgdrv service: %s.", win32_strerror(error));
369*c2e0c6b5SAndroid Build Coastguard Worker           goto out;
370*c2e0c6b5SAndroid Build Coastguard Worker         }
371*c2e0c6b5SAndroid Build Coastguard Worker 
372*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("Kernel Local Debugging Driver (kldbgdrv.sys) is not registered, trying to register it...");
373*c2e0c6b5SAndroid Build Coastguard Worker 
374*c2e0c6b5SAndroid Build Coastguard Worker       if (win32_is_32bit_on_64bit_system())
375*c2e0c6b5SAndroid Build Coastguard Worker         {
376*c2e0c6b5SAndroid Build Coastguard Worker           /* TODO */
377*c2e0c6b5SAndroid Build Coastguard Worker           a->debug("Registering driver from 32-bit process on 64-bit system is not implemented yet.");
378*c2e0c6b5SAndroid Build Coastguard Worker           goto out;
379*c2e0c6b5SAndroid Build Coastguard Worker         }
380*c2e0c6b5SAndroid Build Coastguard Worker 
381*c2e0c6b5SAndroid Build Coastguard Worker       if (!win32_kldbg_register_driver(a, manager, &service))
382*c2e0c6b5SAndroid Build Coastguard Worker         goto out;
383*c2e0c6b5SAndroid Build Coastguard Worker     }
384*c2e0c6b5SAndroid Build Coastguard Worker 
385*c2e0c6b5SAndroid Build Coastguard Worker   if (!StartService(service, 0, NULL))
386*c2e0c6b5SAndroid Build Coastguard Worker     {
387*c2e0c6b5SAndroid Build Coastguard Worker       error = GetLastError();
388*c2e0c6b5SAndroid Build Coastguard Worker       if (error != ERROR_SERVICE_ALREADY_RUNNING)
389*c2e0c6b5SAndroid Build Coastguard Worker         {
390*c2e0c6b5SAndroid Build Coastguard Worker           a->debug("Cannot start kldbgdrv service: %s.", win32_strerror(error));
391*c2e0c6b5SAndroid Build Coastguard Worker           goto out;
392*c2e0c6b5SAndroid Build Coastguard Worker         }
393*c2e0c6b5SAndroid Build Coastguard Worker     }
394*c2e0c6b5SAndroid Build Coastguard Worker 
395*c2e0c6b5SAndroid Build Coastguard Worker   a->debug("Service kldbgdrv successfully started...");
396*c2e0c6b5SAndroid Build Coastguard Worker   ret = 1;
397*c2e0c6b5SAndroid Build Coastguard Worker 
398*c2e0c6b5SAndroid Build Coastguard Worker out:
399*c2e0c6b5SAndroid Build Coastguard Worker   if (service)
400*c2e0c6b5SAndroid Build Coastguard Worker     CloseServiceHandle(service);
401*c2e0c6b5SAndroid Build Coastguard Worker 
402*c2e0c6b5SAndroid Build Coastguard Worker   if (manager)
403*c2e0c6b5SAndroid Build Coastguard Worker     CloseServiceHandle(manager);
404*c2e0c6b5SAndroid Build Coastguard Worker 
405*c2e0c6b5SAndroid Build Coastguard Worker   return ret;
406*c2e0c6b5SAndroid Build Coastguard Worker }
407*c2e0c6b5SAndroid Build Coastguard Worker 
408*c2e0c6b5SAndroid Build Coastguard Worker static int
win32_kldbg_setup(struct pci_access * a)409*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_setup(struct pci_access *a)
410*c2e0c6b5SAndroid Build Coastguard Worker {
411*c2e0c6b5SAndroid Build Coastguard Worker   OSVERSIONINFO version;
412*c2e0c6b5SAndroid Build Coastguard Worker   DWORD ret_len;
413*c2e0c6b5SAndroid Build Coastguard Worker   DWORD error;
414*c2e0c6b5SAndroid Build Coastguard Worker   DWORD id;
415*c2e0c6b5SAndroid Build Coastguard Worker 
416*c2e0c6b5SAndroid Build Coastguard Worker   if (kldbg_dev != INVALID_HANDLE_VALUE)
417*c2e0c6b5SAndroid Build Coastguard Worker     return 1;
418*c2e0c6b5SAndroid Build Coastguard Worker 
419*c2e0c6b5SAndroid Build Coastguard Worker   /* Check for Windows Vista (NT 6.0). */
420*c2e0c6b5SAndroid Build Coastguard Worker   version.dwOSVersionInfoSize = sizeof(version);
421*c2e0c6b5SAndroid Build Coastguard Worker   if (!GetVersionEx(&version) ||
422*c2e0c6b5SAndroid Build Coastguard Worker       version.dwPlatformId != VER_PLATFORM_WIN32_NT ||
423*c2e0c6b5SAndroid Build Coastguard Worker       version.dwMajorVersion < 6)
424*c2e0c6b5SAndroid Build Coastguard Worker     {
425*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("Accessing PCI config space via Kernel Local Debugging Driver requires Windows Vista or higher version.");
426*c2e0c6b5SAndroid Build Coastguard Worker       return 0;
427*c2e0c6b5SAndroid Build Coastguard Worker     }
428*c2e0c6b5SAndroid Build Coastguard Worker 
429*c2e0c6b5SAndroid Build Coastguard Worker   kldbg_dev = CreateFile(TEXT("\\\\.\\kldbgdrv"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
430*c2e0c6b5SAndroid Build Coastguard Worker   if (kldbg_dev == INVALID_HANDLE_VALUE)
431*c2e0c6b5SAndroid Build Coastguard Worker     {
432*c2e0c6b5SAndroid Build Coastguard Worker       error = GetLastError();
433*c2e0c6b5SAndroid Build Coastguard Worker       if (error != ERROR_FILE_NOT_FOUND)
434*c2e0c6b5SAndroid Build Coastguard Worker         {
435*c2e0c6b5SAndroid Build Coastguard Worker           a->debug("Cannot open \"\\\\.\\kldbgdrv\" device: %s.", win32_strerror(error));
436*c2e0c6b5SAndroid Build Coastguard Worker           return 0;
437*c2e0c6b5SAndroid Build Coastguard Worker         }
438*c2e0c6b5SAndroid Build Coastguard Worker 
439*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("Kernel Local Debugging Driver (kldbgdrv.sys) is not running, trying to start it...");
440*c2e0c6b5SAndroid Build Coastguard Worker 
441*c2e0c6b5SAndroid Build Coastguard Worker       if (!win32_kldbg_start_driver(a))
442*c2e0c6b5SAndroid Build Coastguard Worker         return 0;
443*c2e0c6b5SAndroid Build Coastguard Worker 
444*c2e0c6b5SAndroid Build Coastguard Worker       kldbg_dev = CreateFile(TEXT("\\\\.\\kldbgdrv"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
445*c2e0c6b5SAndroid Build Coastguard Worker       if (kldbg_dev == INVALID_HANDLE_VALUE)
446*c2e0c6b5SAndroid Build Coastguard Worker         {
447*c2e0c6b5SAndroid Build Coastguard Worker           error = GetLastError();
448*c2e0c6b5SAndroid Build Coastguard Worker           a->debug("Cannot open \"\\\\.\\kldbgdrv\" device: %s.", win32_strerror(error));
449*c2e0c6b5SAndroid Build Coastguard Worker           return 0;
450*c2e0c6b5SAndroid Build Coastguard Worker         }
451*c2e0c6b5SAndroid Build Coastguard Worker     }
452*c2e0c6b5SAndroid Build Coastguard Worker 
453*c2e0c6b5SAndroid Build Coastguard Worker   /*
454*c2e0c6b5SAndroid Build Coastguard Worker    * Try to read PCI id register from PCI device 0000:00:00.0.
455*c2e0c6b5SAndroid Build Coastguard Worker    * If this device does not exist and kldbg API is working then
456*c2e0c6b5SAndroid Build Coastguard Worker    * kldbg returns success with read value 0xffffffff.
457*c2e0c6b5SAndroid Build Coastguard Worker    */
458*c2e0c6b5SAndroid Build Coastguard Worker   if (win32_kldbg_pci_bus_data(FALSE, 0, 0, 0, 0, 0, &id, sizeof(id), &ret_len) && ret_len == sizeof(id))
459*c2e0c6b5SAndroid Build Coastguard Worker     return 1;
460*c2e0c6b5SAndroid Build Coastguard Worker 
461*c2e0c6b5SAndroid Build Coastguard Worker   error = GetLastError();
462*c2e0c6b5SAndroid Build Coastguard Worker 
463*c2e0c6b5SAndroid Build Coastguard Worker   a->debug("Cannot read PCI config space via Kernel Local Debugging Driver: %s.", win32_strerror(error));
464*c2e0c6b5SAndroid Build Coastguard Worker 
465*c2e0c6b5SAndroid Build Coastguard Worker   if (error != ERROR_ACCESS_DENIED)
466*c2e0c6b5SAndroid Build Coastguard Worker     {
467*c2e0c6b5SAndroid Build Coastguard Worker       CloseHandle(kldbg_dev);
468*c2e0c6b5SAndroid Build Coastguard Worker       kldbg_dev = INVALID_HANDLE_VALUE;
469*c2e0c6b5SAndroid Build Coastguard Worker       return 0;
470*c2e0c6b5SAndroid Build Coastguard Worker     }
471*c2e0c6b5SAndroid Build Coastguard Worker 
472*c2e0c6b5SAndroid Build Coastguard Worker   a->debug("..Trying again with Debug privilege...");
473*c2e0c6b5SAndroid Build Coastguard Worker 
474*c2e0c6b5SAndroid Build Coastguard Worker   if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid_debug_privilege))
475*c2e0c6b5SAndroid Build Coastguard Worker     {
476*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("Debug privilege is not supported.");
477*c2e0c6b5SAndroid Build Coastguard Worker       CloseHandle(kldbg_dev);
478*c2e0c6b5SAndroid Build Coastguard Worker       kldbg_dev = INVALID_HANDLE_VALUE;
479*c2e0c6b5SAndroid Build Coastguard Worker       return 0;
480*c2e0c6b5SAndroid Build Coastguard Worker     }
481*c2e0c6b5SAndroid Build Coastguard Worker 
482*c2e0c6b5SAndroid Build Coastguard Worker   if (!win32_enable_privilege(luid_debug_privilege, &revert_token, &revert_only_privilege))
483*c2e0c6b5SAndroid Build Coastguard Worker     {
484*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("Process does not have right to enable Debug privilege.");
485*c2e0c6b5SAndroid Build Coastguard Worker       CloseHandle(kldbg_dev);
486*c2e0c6b5SAndroid Build Coastguard Worker       kldbg_dev = INVALID_HANDLE_VALUE;
487*c2e0c6b5SAndroid Build Coastguard Worker       return 0;
488*c2e0c6b5SAndroid Build Coastguard Worker     }
489*c2e0c6b5SAndroid Build Coastguard Worker 
490*c2e0c6b5SAndroid Build Coastguard Worker   if (win32_kldbg_pci_bus_data(FALSE, 0, 0, 0, 0, 0, &id, sizeof(id), &ret_len) && ret_len == sizeof(id))
491*c2e0c6b5SAndroid Build Coastguard Worker     {
492*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("Succeeded.");
493*c2e0c6b5SAndroid Build Coastguard Worker       debug_privilege_enabled = TRUE;
494*c2e0c6b5SAndroid Build Coastguard Worker       return 1;
495*c2e0c6b5SAndroid Build Coastguard Worker     }
496*c2e0c6b5SAndroid Build Coastguard Worker 
497*c2e0c6b5SAndroid Build Coastguard Worker   error = GetLastError();
498*c2e0c6b5SAndroid Build Coastguard Worker 
499*c2e0c6b5SAndroid Build Coastguard Worker   a->debug("Cannot read PCI config space via Kernel Local Debugging Driver: %s.", win32_strerror(error));
500*c2e0c6b5SAndroid Build Coastguard Worker 
501*c2e0c6b5SAndroid Build Coastguard Worker   CloseHandle(kldbg_dev);
502*c2e0c6b5SAndroid Build Coastguard Worker   kldbg_dev = INVALID_HANDLE_VALUE;
503*c2e0c6b5SAndroid Build Coastguard Worker 
504*c2e0c6b5SAndroid Build Coastguard Worker   win32_revert_privilege(luid_debug_privilege, revert_token, revert_only_privilege);
505*c2e0c6b5SAndroid Build Coastguard Worker   revert_token = NULL;
506*c2e0c6b5SAndroid Build Coastguard Worker   revert_only_privilege = FALSE;
507*c2e0c6b5SAndroid Build Coastguard Worker   return 0;
508*c2e0c6b5SAndroid Build Coastguard Worker }
509*c2e0c6b5SAndroid Build Coastguard Worker 
510*c2e0c6b5SAndroid Build Coastguard Worker static int
win32_kldbg_detect(struct pci_access * a)511*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_detect(struct pci_access *a)
512*c2e0c6b5SAndroid Build Coastguard Worker {
513*c2e0c6b5SAndroid Build Coastguard Worker   if (!win32_kldbg_setup(a))
514*c2e0c6b5SAndroid Build Coastguard Worker     return 0;
515*c2e0c6b5SAndroid Build Coastguard Worker 
516*c2e0c6b5SAndroid Build Coastguard Worker   return 1;
517*c2e0c6b5SAndroid Build Coastguard Worker }
518*c2e0c6b5SAndroid Build Coastguard Worker 
519*c2e0c6b5SAndroid Build Coastguard Worker static void
win32_kldbg_init(struct pci_access * a)520*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_init(struct pci_access *a)
521*c2e0c6b5SAndroid Build Coastguard Worker {
522*c2e0c6b5SAndroid Build Coastguard Worker   if (!win32_kldbg_setup(a))
523*c2e0c6b5SAndroid Build Coastguard Worker     {
524*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("\n");
525*c2e0c6b5SAndroid Build Coastguard Worker       a->error("PCI config space via Kernel Local Debugging Driver cannot be accessed.");
526*c2e0c6b5SAndroid Build Coastguard Worker     }
527*c2e0c6b5SAndroid Build Coastguard Worker }
528*c2e0c6b5SAndroid Build Coastguard Worker 
529*c2e0c6b5SAndroid Build Coastguard Worker static void
win32_kldbg_cleanup(struct pci_access * a UNUSED)530*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_cleanup(struct pci_access *a UNUSED)
531*c2e0c6b5SAndroid Build Coastguard Worker {
532*c2e0c6b5SAndroid Build Coastguard Worker   if (kldbg_dev == INVALID_HANDLE_VALUE)
533*c2e0c6b5SAndroid Build Coastguard Worker     return;
534*c2e0c6b5SAndroid Build Coastguard Worker 
535*c2e0c6b5SAndroid Build Coastguard Worker   CloseHandle(kldbg_dev);
536*c2e0c6b5SAndroid Build Coastguard Worker   kldbg_dev = INVALID_HANDLE_VALUE;
537*c2e0c6b5SAndroid Build Coastguard Worker 
538*c2e0c6b5SAndroid Build Coastguard Worker   if (debug_privilege_enabled)
539*c2e0c6b5SAndroid Build Coastguard Worker     {
540*c2e0c6b5SAndroid Build Coastguard Worker       win32_revert_privilege(luid_debug_privilege, revert_token, revert_only_privilege);
541*c2e0c6b5SAndroid Build Coastguard Worker       revert_token = NULL;
542*c2e0c6b5SAndroid Build Coastguard Worker       revert_only_privilege = FALSE;
543*c2e0c6b5SAndroid Build Coastguard Worker       debug_privilege_enabled = FALSE;
544*c2e0c6b5SAndroid Build Coastguard Worker     }
545*c2e0c6b5SAndroid Build Coastguard Worker }
546*c2e0c6b5SAndroid Build Coastguard Worker 
547*c2e0c6b5SAndroid Build Coastguard Worker struct acpi_mcfg {
548*c2e0c6b5SAndroid Build Coastguard Worker   char signature[4];
549*c2e0c6b5SAndroid Build Coastguard Worker   u32 length;
550*c2e0c6b5SAndroid Build Coastguard Worker   u8 revision;
551*c2e0c6b5SAndroid Build Coastguard Worker   u8 checksum;
552*c2e0c6b5SAndroid Build Coastguard Worker   char oem_id[6];
553*c2e0c6b5SAndroid Build Coastguard Worker   char oem_table_id[8];
554*c2e0c6b5SAndroid Build Coastguard Worker   u32 oem_revision;
555*c2e0c6b5SAndroid Build Coastguard Worker   char asl_compiler_id[4];
556*c2e0c6b5SAndroid Build Coastguard Worker   u32 asl_compiler_revision;
557*c2e0c6b5SAndroid Build Coastguard Worker   u64 reserved;
558*c2e0c6b5SAndroid Build Coastguard Worker   struct {
559*c2e0c6b5SAndroid Build Coastguard Worker     u64 address;
560*c2e0c6b5SAndroid Build Coastguard Worker     u16 pci_segment;
561*c2e0c6b5SAndroid Build Coastguard Worker     u8 start_bus_number;
562*c2e0c6b5SAndroid Build Coastguard Worker     u8 end_bus_number;
563*c2e0c6b5SAndroid Build Coastguard Worker     u32 reserved;
564*c2e0c6b5SAndroid Build Coastguard Worker   } allocations[0];
565*c2e0c6b5SAndroid Build Coastguard Worker } PCI_PACKED;
566*c2e0c6b5SAndroid Build Coastguard Worker 
567*c2e0c6b5SAndroid Build Coastguard Worker static void
win32_kldbg_scan(struct pci_access * a)568*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_scan(struct pci_access *a)
569*c2e0c6b5SAndroid Build Coastguard Worker {
570*c2e0c6b5SAndroid Build Coastguard Worker   /*
571*c2e0c6b5SAndroid Build Coastguard Worker    * There is no kldbg API to retrieve list of PCI segments. WinDBG pci plugin
572*c2e0c6b5SAndroid Build Coastguard Worker    * kext.dll loads debug symbols from pci.pdb file for kernel module pci.sys.
573*c2e0c6b5SAndroid Build Coastguard Worker    * Then it reads kernel memory which belongs to PciSegmentList local variable
574*c2e0c6b5SAndroid Build Coastguard Worker    * which is the first entry of struct _PCI_SEGMENT linked list. And then it
575*c2e0c6b5SAndroid Build Coastguard Worker    * iterates all entries in linked list and reads SegmentNumber for each entry.
576*c2e0c6b5SAndroid Build Coastguard Worker    *
577*c2e0c6b5SAndroid Build Coastguard Worker    * This is extremly ugly hack and does not work on systems without installed
578*c2e0c6b5SAndroid Build Coastguard Worker    * kernel debug symbol files.
579*c2e0c6b5SAndroid Build Coastguard Worker    *
580*c2e0c6b5SAndroid Build Coastguard Worker    * Do something less ugly. Retrieve ACPI MCFG table via GetSystemFirmwareTable
581*c2e0c6b5SAndroid Build Coastguard Worker    * and parse all PCI segment numbers from it. ACPI MCFG table contains PCIe
582*c2e0c6b5SAndroid Build Coastguard Worker    * ECAM definitions, so all PCI segment numbers.
583*c2e0c6b5SAndroid Build Coastguard Worker    */
584*c2e0c6b5SAndroid Build Coastguard Worker 
585*c2e0c6b5SAndroid Build Coastguard Worker   UINT (*WINAPI MyGetSystemFirmwareTable)(DWORD FirmwareTableProviderSignature, DWORD FirmwareTableID, PVOID pFirmwareTableBuffer, DWORD BufferSize);
586*c2e0c6b5SAndroid Build Coastguard Worker   int i, allocations_count;
587*c2e0c6b5SAndroid Build Coastguard Worker   struct acpi_mcfg *mcfg;
588*c2e0c6b5SAndroid Build Coastguard Worker   HMODULE kernel32;
589*c2e0c6b5SAndroid Build Coastguard Worker   byte *segments;
590*c2e0c6b5SAndroid Build Coastguard Worker   DWORD error;
591*c2e0c6b5SAndroid Build Coastguard Worker   DWORD size;
592*c2e0c6b5SAndroid Build Coastguard Worker 
593*c2e0c6b5SAndroid Build Coastguard Worker   /* Always scan PCI segment 0. */
594*c2e0c6b5SAndroid Build Coastguard Worker   pci_generic_scan_domain(a, 0);
595*c2e0c6b5SAndroid Build Coastguard Worker 
596*c2e0c6b5SAndroid Build Coastguard Worker   kernel32 = GetModuleHandle(TEXT("kernel32.dll"));
597*c2e0c6b5SAndroid Build Coastguard Worker   if (!kernel32)
598*c2e0c6b5SAndroid Build Coastguard Worker     return;
599*c2e0c6b5SAndroid Build Coastguard Worker 
600*c2e0c6b5SAndroid Build Coastguard Worker   /* Function GetSystemFirmwareTable() is available since Windows Vista. */
601*c2e0c6b5SAndroid Build Coastguard Worker   MyGetSystemFirmwareTable = (void *)GetProcAddress(kernel32, "GetSystemFirmwareTable");
602*c2e0c6b5SAndroid Build Coastguard Worker   if (!MyGetSystemFirmwareTable)
603*c2e0c6b5SAndroid Build Coastguard Worker     return;
604*c2e0c6b5SAndroid Build Coastguard Worker 
605*c2e0c6b5SAndroid Build Coastguard Worker   /* 0x41435049 = 'ACPI', 0x4746434D = 'MCFG' */
606*c2e0c6b5SAndroid Build Coastguard Worker   size = MyGetSystemFirmwareTable(0x41435049, 0x4746434D, NULL, 0);
607*c2e0c6b5SAndroid Build Coastguard Worker   if (size == 0)
608*c2e0c6b5SAndroid Build Coastguard Worker     {
609*c2e0c6b5SAndroid Build Coastguard Worker       error = GetLastError();
610*c2e0c6b5SAndroid Build Coastguard Worker       if (error == ERROR_INVALID_FUNCTION) /* ACPI is not present, so only PCI segment 0 is available. */
611*c2e0c6b5SAndroid Build Coastguard Worker         return;
612*c2e0c6b5SAndroid Build Coastguard Worker       else if (error == ERROR_NOT_FOUND) /* MCFG table is not present, so only PCI segment 0 is available. */
613*c2e0c6b5SAndroid Build Coastguard Worker         return;
614*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("Cannot retrieve ACPI MCFG table: %s.\n", win32_strerror(error));
615*c2e0c6b5SAndroid Build Coastguard Worker       return;
616*c2e0c6b5SAndroid Build Coastguard Worker     }
617*c2e0c6b5SAndroid Build Coastguard Worker 
618*c2e0c6b5SAndroid Build Coastguard Worker   mcfg = pci_malloc(a, size);
619*c2e0c6b5SAndroid Build Coastguard Worker 
620*c2e0c6b5SAndroid Build Coastguard Worker   if (MyGetSystemFirmwareTable(0x41435049, 0x4746434D, mcfg, size) != size)
621*c2e0c6b5SAndroid Build Coastguard Worker     {
622*c2e0c6b5SAndroid Build Coastguard Worker       error = GetLastError();
623*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("Cannot retrieve ACPI MCFG table: %s.\n", win32_strerror(error));
624*c2e0c6b5SAndroid Build Coastguard Worker       pci_mfree(mcfg);
625*c2e0c6b5SAndroid Build Coastguard Worker       return;
626*c2e0c6b5SAndroid Build Coastguard Worker     }
627*c2e0c6b5SAndroid Build Coastguard Worker 
628*c2e0c6b5SAndroid Build Coastguard Worker   if (size < sizeof(*mcfg) || size < mcfg->length)
629*c2e0c6b5SAndroid Build Coastguard Worker     {
630*c2e0c6b5SAndroid Build Coastguard Worker       a->debug("ACPI MCFG table is broken.\n");
631*c2e0c6b5SAndroid Build Coastguard Worker       pci_mfree(mcfg);
632*c2e0c6b5SAndroid Build Coastguard Worker       return;
633*c2e0c6b5SAndroid Build Coastguard Worker     }
634*c2e0c6b5SAndroid Build Coastguard Worker 
635*c2e0c6b5SAndroid Build Coastguard Worker   segments = pci_malloc(a, 0xFFFF/8);
636*c2e0c6b5SAndroid Build Coastguard Worker   memset(segments, 0, 0xFFFF/8);
637*c2e0c6b5SAndroid Build Coastguard Worker 
638*c2e0c6b5SAndroid Build Coastguard Worker   /* Scan all MCFG allocations and set available PCI segments into bit field. */
639*c2e0c6b5SAndroid Build Coastguard Worker   allocations_count = (mcfg->length - ((unsigned char *)&mcfg->allocations - (unsigned char *)mcfg)) / sizeof(mcfg->allocations[0]);
640*c2e0c6b5SAndroid Build Coastguard Worker   for (i = 0; i < allocations_count; i++)
641*c2e0c6b5SAndroid Build Coastguard Worker     segments[mcfg->allocations[i].pci_segment / 8] |= 1 << (mcfg->allocations[i].pci_segment % 8);
642*c2e0c6b5SAndroid Build Coastguard Worker 
643*c2e0c6b5SAndroid Build Coastguard Worker   /* Skip PCI segment 0 which was already scanned. */
644*c2e0c6b5SAndroid Build Coastguard Worker   for (i = 1; i < 0xFFFF; i++)
645*c2e0c6b5SAndroid Build Coastguard Worker     if (segments[i / 8] & (1 << (i % 8)))
646*c2e0c6b5SAndroid Build Coastguard Worker       pci_generic_scan_domain(a, i);
647*c2e0c6b5SAndroid Build Coastguard Worker 
648*c2e0c6b5SAndroid Build Coastguard Worker   pci_mfree(segments);
649*c2e0c6b5SAndroid Build Coastguard Worker   pci_mfree(mcfg);
650*c2e0c6b5SAndroid Build Coastguard Worker }
651*c2e0c6b5SAndroid Build Coastguard Worker 
652*c2e0c6b5SAndroid Build Coastguard Worker static BOOL
win32_kldbg_pci_bus_data(BOOL WriteBusData,USHORT SegmentNumber,BYTE BusNumber,BYTE DeviceNumber,BYTE FunctionNumber,USHORT Address,PVOID Buffer,ULONG BufferSize,LPDWORD Length)653*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_pci_bus_data(BOOL WriteBusData, USHORT SegmentNumber, BYTE BusNumber, BYTE DeviceNumber, BYTE FunctionNumber, USHORT Address, PVOID Buffer, ULONG BufferSize, LPDWORD Length)
654*c2e0c6b5SAndroid Build Coastguard Worker {
655*c2e0c6b5SAndroid Build Coastguard Worker   KLDBG kldbg_cmd;
656*c2e0c6b5SAndroid Build Coastguard Worker   SYSDBG_BUS_DATA sysdbg_cmd;
657*c2e0c6b5SAndroid Build Coastguard Worker   PCI_SLOT_NUMBER pci_slot;
658*c2e0c6b5SAndroid Build Coastguard Worker   PCI_SEGMENT_BUS_NUMBER pci_seg_bus;
659*c2e0c6b5SAndroid Build Coastguard Worker 
660*c2e0c6b5SAndroid Build Coastguard Worker   memset(&pci_slot, 0, sizeof(pci_slot));
661*c2e0c6b5SAndroid Build Coastguard Worker   memset(&sysdbg_cmd, 0, sizeof(sysdbg_cmd));
662*c2e0c6b5SAndroid Build Coastguard Worker   memset(&pci_seg_bus, 0, sizeof(pci_seg_bus));
663*c2e0c6b5SAndroid Build Coastguard Worker 
664*c2e0c6b5SAndroid Build Coastguard Worker   sysdbg_cmd.Address = Address;
665*c2e0c6b5SAndroid Build Coastguard Worker   sysdbg_cmd.Buffer = Buffer;
666*c2e0c6b5SAndroid Build Coastguard Worker   sysdbg_cmd.Request = BufferSize;
667*c2e0c6b5SAndroid Build Coastguard Worker   sysdbg_cmd.BusDataType = PCIConfiguration;
668*c2e0c6b5SAndroid Build Coastguard Worker   pci_seg_bus.u.bits.BusNumber = BusNumber;
669*c2e0c6b5SAndroid Build Coastguard Worker   pci_seg_bus.u.bits.SegmentNumber = SegmentNumber;
670*c2e0c6b5SAndroid Build Coastguard Worker   sysdbg_cmd.BusNumber = pci_seg_bus.u.AsULONG;
671*c2e0c6b5SAndroid Build Coastguard Worker   pci_slot.u.bits.DeviceNumber = DeviceNumber;
672*c2e0c6b5SAndroid Build Coastguard Worker   pci_slot.u.bits.FunctionNumber = FunctionNumber;
673*c2e0c6b5SAndroid Build Coastguard Worker   sysdbg_cmd.SlotNumber = pci_slot.u.AsULONG;
674*c2e0c6b5SAndroid Build Coastguard Worker 
675*c2e0c6b5SAndroid Build Coastguard Worker   kldbg_cmd.Command = WriteBusData ? SysDbgWriteBusData : SysDbgReadBusData;
676*c2e0c6b5SAndroid Build Coastguard Worker   kldbg_cmd.Buffer = &sysdbg_cmd;
677*c2e0c6b5SAndroid Build Coastguard Worker   kldbg_cmd.BufferLength = sizeof(sysdbg_cmd);
678*c2e0c6b5SAndroid Build Coastguard Worker 
679*c2e0c6b5SAndroid Build Coastguard Worker   *Length = 0;
680*c2e0c6b5SAndroid Build Coastguard Worker   return DeviceIoControl(kldbg_dev, IOCTL_KLDBG, &kldbg_cmd, sizeof(kldbg_cmd), &sysdbg_cmd, sizeof(sysdbg_cmd), Length, NULL);
681*c2e0c6b5SAndroid Build Coastguard Worker }
682*c2e0c6b5SAndroid Build Coastguard Worker 
683*c2e0c6b5SAndroid Build Coastguard Worker static int
win32_kldbg_read(struct pci_dev * d,int pos,byte * buf,int len)684*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_read(struct pci_dev *d, int pos, byte *buf, int len)
685*c2e0c6b5SAndroid Build Coastguard Worker {
686*c2e0c6b5SAndroid Build Coastguard Worker   DWORD ret_len;
687*c2e0c6b5SAndroid Build Coastguard Worker 
688*c2e0c6b5SAndroid Build Coastguard Worker   if ((unsigned int)d->domain > 0xffff)
689*c2e0c6b5SAndroid Build Coastguard Worker     return 0;
690*c2e0c6b5SAndroid Build Coastguard Worker 
691*c2e0c6b5SAndroid Build Coastguard Worker   if (!win32_kldbg_pci_bus_data(FALSE, d->domain, d->bus, d->dev, d->func, pos, buf, len, &ret_len))
692*c2e0c6b5SAndroid Build Coastguard Worker     return 0;
693*c2e0c6b5SAndroid Build Coastguard Worker 
694*c2e0c6b5SAndroid Build Coastguard Worker   if (ret_len != (unsigned int)len)
695*c2e0c6b5SAndroid Build Coastguard Worker     return 0;
696*c2e0c6b5SAndroid Build Coastguard Worker 
697*c2e0c6b5SAndroid Build Coastguard Worker   return 1;
698*c2e0c6b5SAndroid Build Coastguard Worker }
699*c2e0c6b5SAndroid Build Coastguard Worker 
700*c2e0c6b5SAndroid Build Coastguard Worker static int
win32_kldbg_write(struct pci_dev * d,int pos,byte * buf,int len)701*c2e0c6b5SAndroid Build Coastguard Worker win32_kldbg_write(struct pci_dev *d, int pos, byte *buf, int len)
702*c2e0c6b5SAndroid Build Coastguard Worker {
703*c2e0c6b5SAndroid Build Coastguard Worker   DWORD ret_len;
704*c2e0c6b5SAndroid Build Coastguard Worker 
705*c2e0c6b5SAndroid Build Coastguard Worker   if ((unsigned int)d->domain > 0xffff)
706*c2e0c6b5SAndroid Build Coastguard Worker     return 0;
707*c2e0c6b5SAndroid Build Coastguard Worker 
708*c2e0c6b5SAndroid Build Coastguard Worker   if (!win32_kldbg_pci_bus_data(TRUE, d->domain, d->bus, d->dev, d->func, pos, buf, len, &ret_len))
709*c2e0c6b5SAndroid Build Coastguard Worker     return 0;
710*c2e0c6b5SAndroid Build Coastguard Worker 
711*c2e0c6b5SAndroid Build Coastguard Worker   if (ret_len != (unsigned int)len)
712*c2e0c6b5SAndroid Build Coastguard Worker     return 0;
713*c2e0c6b5SAndroid Build Coastguard Worker 
714*c2e0c6b5SAndroid Build Coastguard Worker   return 1;
715*c2e0c6b5SAndroid Build Coastguard Worker }
716*c2e0c6b5SAndroid Build Coastguard Worker 
717*c2e0c6b5SAndroid Build Coastguard Worker struct pci_methods pm_win32_kldbg = {
718*c2e0c6b5SAndroid Build Coastguard Worker   .name = "win32-kldbg",
719*c2e0c6b5SAndroid Build Coastguard Worker   .help = "Win32 PCI config space access using Kernel Local Debugging Driver",
720*c2e0c6b5SAndroid Build Coastguard Worker   .detect = win32_kldbg_detect,
721*c2e0c6b5SAndroid Build Coastguard Worker   .init = win32_kldbg_init,
722*c2e0c6b5SAndroid Build Coastguard Worker   .cleanup = win32_kldbg_cleanup,
723*c2e0c6b5SAndroid Build Coastguard Worker   .scan = win32_kldbg_scan,
724*c2e0c6b5SAndroid Build Coastguard Worker   .fill_info = pci_generic_fill_info,
725*c2e0c6b5SAndroid Build Coastguard Worker   .read = win32_kldbg_read,
726*c2e0c6b5SAndroid Build Coastguard Worker   .write = win32_kldbg_write,
727*c2e0c6b5SAndroid Build Coastguard Worker };
728