ReactOS 0.4.17-dev-1164-g974a446
ksedb.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Kernel Shim Engine driver database (drvmain.sdb)
5 * COPYRIGHT: Copyright 2026 Mark Jansen <mark.jansen@reactos.org>
6 */
7
8#include <ntoskrnl.h>
9
10/* Win32 types used by the apphelp shim database reader */
11typedef int BOOL;
12#ifndef WINAPI
13#define WINAPI NTAPI
14#endif
15
16/* Pool tag from internal/tag.h, which has the same name as a database tag */
17#undef TAG_SHIM
18
19#include <appcompat/sdbtypes.h>
20#include <appcompat/sdbtagid.h>
21
22#define NDEBUG
23#include <debug.h>
24
25// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/kshim/drvmain.htm
26
27/* The database is read with the apphelp shim database reader (sdbread.c) */
35
36#define SDB_HEADER_SIZE 12
37#define SDB_HEADER_MAGIC 'fbds'
38
41
42
43/* Helpers that sdbread.c expects from the rest of apphelp */
44
46
47BOOL
53 ...)
54{
55 va_list ap;
56
58
59 DbgPrint("KSE: [%s] ", FunctionName);
62 va_end(ap);
63 return TRUE;
64}
65
66BOOL
69 _In_ PDB pdb,
70 _In_ TAGID tagid,
72{
73 TAG tag = SdbGetTagFromTagID(pdb, tagid);
74 if (tag == TAG_NULL)
75 return FALSE;
76 return (tag & TAG_TYPE_MASK) == type;
77}
78
79BOOL
83{
84 static const GUID NullGuid = { 0 };
85 return IsEqualGUID(Guid, &NullGuid);
86}
87
88
89CODE_SEG("INIT")
93 _In_ PVOID DatabaseImage,
94 _In_ ULONG DatabaseSize)
95{
96 PULONG Header = DatabaseImage;
98
99 if (!DatabaseImage || DatabaseSize <= SDB_HEADER_SIZE || Header[2] != SDB_HEADER_MAGIC)
101
102 /* The loader block is freed after boot, so keep a copy */
104 if (!Data)
106 RtlCopyMemory(Data, DatabaseImage, DatabaseSize);
107
110 KseDriverDatabase.size = DatabaseSize;
114
117 {
121 }
122
123 DPRINT1("KSE: Loaded driver database version %lu.%lu (%lu bytes)\n",
125 return STATUS_SUCCESS;
126}
127
128static BOOLEAN
131 _In_ TAG Tag,
133{
135 PWSTR Ptr;
136
138 if (!Ptr)
139 return FALSE;
140
143}
144
145/* All attributes of a MATCHING_FILE must match the driver */
146static BOOLEAN
150{
151 static const UNICODE_STRING Self = RTL_CONSTANT_STRING(L"*");
152 PIMAGE_NT_HEADERS NtHeaders;
153 TAGID Attribute;
154 TAG Tag;
155
156 /* Only the driver itself can be checked here */
158 !KsepDbStringEquals(MatchingFile, TAG_NAME, &LdrEntry->BaseDllName))
159 {
160 return FALSE;
161 }
162
163 NtHeaders = RtlImageNtHeader(LdrEntry->DllBase);
164 if (!NtHeaders)
165 return FALSE;
166
168 Attribute != TAGID_NULL;
169 Attribute = SdbGetNextChild(&KseDriverDatabase, MatchingFile, Attribute))
170 {
172 switch (Tag)
173 {
174 case TAG_NAME:
175 break;
176
177 case TAG_LINK_DATE:
178 if (SdbReadDWORDTag(&KseDriverDatabase, Attribute, 0) != NtHeaders->FileHeader.TimeDateStamp)
179 return FALSE;
180 break;
181
182 case TAG_CHECKSUM:
183 if (SdbReadDWORDTag(&KseDriverDatabase, Attribute, 0) != NtHeaders->OptionalHeader.CheckSum)
184 return FALSE;
185 break;
186
187 default:
188 /* Do not shim a driver based on attributes that were not checked */
189 DPRINT1("KSE: Unsupported matching attribute 0x%x for %wZ\n", Tag, &LdrEntry->BaseDllName);
190 return FALSE;
191 }
192 }
193
194 return TRUE;
195}
196
197VOID
198NTAPI
201 _Inout_ PKSE_SHIM* Shims,
202 _Inout_ PULONG NumberOfShims)
203{
205 UNICODE_STRING ShimName;
206 PWSTR Name;
207 BOOLEAN Match;
208
210 return;
211
215 {
216 if (!KsepDbStringEquals(Driver, TAG_NAME, &LdrEntry->BaseDllName))
217 continue;
218
219 Match = TRUE;
221 MatchingFile != TAGID_NULL && Match;
223 {
224 Match = KsepDbMatchingFileMatches(MatchingFile, LdrEntry);
225 }
226
227 if (!Match)
228 {
229 DPRINT1("KSE: %wZ is in the driver database, but does not match\n", &LdrEntry->BaseDllName);
230 continue;
231 }
232
236 {
238 if (!Name)
239 continue;
240
241 RtlInitUnicodeString(&ShimName, Name);
242 KsepAddShimByName(&ShimName, Shims, NumberOfShims);
243 }
244 }
245}
#define CODE_SEG(...)
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char * FunctionName
Definition: acpixf.h:1279
unsigned char BOOLEAN
Definition: actypes.h:127
DWORD TAGID
NTSYSAPI ULONG NTAPI vDbgPrintEx(_In_ ULONG ComponentId, _In_ ULONG Level, _In_z_ PCCH Format, _In_ va_list ap)
#define DPFLTR_ERROR_LEVEL
Definition: main.cpp:32
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
Definition: Header.h:9
static PDB pdb
Definition: db.cpp:173
#define TAGID_NULL
Definition: db.cpp:38
#define TAG_STRINGTABLE
Definition: db.cpp:94
#define TAGID_ROOT
Definition: db.cpp:39
#define TAG_MATCHING_FILE
Definition: db.cpp:88
#define TAG_DATABASE
Definition: db.cpp:85
LPWSTR Name
Definition: desk.c:124
_In_ ULONG _In_ UCHAR Level
Definition: dispmprt.h:1329
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
#define RtlImageNtHeader
Definition: compat.h:806
#define __cdecl
Definition: corecrt.h:121
#define va_end(v)
Definition: stdarg.h:28
#define va_start(v, l)
Definition: stdarg.h:26
char * va_list
Definition: vadefs.h:50
@ DPFLTR_DEFAULT_ID
Definition: dpfilter.h:129
return ret
Definition: mutex.c:147
#define L(x)
Definition: resources.c:13
r parent
Definition: btrfs.c:3010
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define DbgPrint
Definition: hal.h:12
VOID NTAPI KsepAddShimByName(_In_ PCUNICODE_STRING Name, _Inout_ PKSE_SHIM *Shims, _Inout_ PULONG NumberOfShims)
Definition: kse.c:107
int BOOL
Definition: ksedb.c:11
static BOOLEAN KsepDbStringEquals(_In_ TAGID Parent, _In_ TAG Tag, _In_ PCUNICODE_STRING String)
Definition: ksedb.c:129
TAG WINAPI SdbGetTagFromTagID(PDB pdb, TAGID tagid)
Definition: sdbread.c:93
TAGID WINAPI SdbFindFirstTag(PDB pdb, TAGID parent, TAG tag)
Definition: sdbread.c:208
VOID NTAPI KseDbGetShimsForDriver(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry, _Inout_ PKSE_SHIM *Shims, _Inout_ PULONG NumberOfShims)
Definition: ksedb.c:199
TAGID WINAPI SdbGetFirstChild(PDB pdb, TAGID parent)
Definition: sdbread.c:142
ULONG g_ShimDebugLevel
Definition: ksedb.c:45
TAGID WINAPI SdbGetNextChild(PDB pdb, TAGID parent, TAGID prev_child)
Definition: sdbread.c:171
static DB KseDriverDatabase
Definition: ksedb.c:39
#define SDB_HEADER_MAGIC
Definition: ksedb.c:37
static TAGID KseDatabaseRoot
Definition: ksedb.c:40
BOOL WINAPI SdbpCheckTagIDType(_In_ PDB pdb, _In_ TAGID tagid, _In_ WORD type)
Definition: ksedb.c:68
NTSTATUS NTAPI KseDbInitialize(_In_ PVOID DatabaseImage, _In_ ULONG DatabaseSize)
Definition: ksedb.c:92
BOOL __cdecl ShimDbgPrint(_In_ ULONG Level, _In_ PCSTR FunctionName, _In_z_ _Printf_format_string_ PCSTR Format,...)
Definition: ksedb.c:49
static BOOLEAN KsepDbMatchingFileMatches(_In_ TAGID MatchingFile, _In_ PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: ksedb.c:147
#define WINAPI
Definition: ksedb.c:13
BOOL WINAPI SdbIsNullGUID(_In_ CONST GUID *Guid)
Definition: ksedb.c:81
TAGID WINAPI SdbFindNextTag(PDB pdb, TAGID parent, TAGID prev_child)
Definition: sdbread.c:231
#define SDB_HEADER_SIZE
Definition: ksedb.c:36
DWORD WINAPI SdbReadDWORDTag(PDB pdb, TAGID tagid, DWORD ret)
Definition: sdbread.c:305
LPWSTR WINAPI SdbGetStringTagPtr(PDB pdb, TAGID tagid)
Definition: sdbread.c:375
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define TAG_CHECKSUM
Definition: apphelp.c:47
#define TAG_LINK_DATE
Definition: apphelp.c:56
#define TAG_NULL
Definition: apphelp.c:45
#define _Inout_
Definition: no_sal2.h:162
#define _In_z_
Definition: no_sal2.h:164
#define _In_
Definition: no_sal2.h:158
#define _Printf_format_string_
Definition: no_sal2.h:356
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:453
#define CONST
Definition: pedump.c:81
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define TAG_KSHIM_REF
Definition: sdbtagid.h:192
#define TAG_KDRIVER
Definition: sdbtagid.h:190
#define STATUS_SUCCESS
Definition: shellext.h:65
#define TAG_TYPE_MASK
Definition: shimdbg.c:106
Definition: sdbtypes.h:24
DWORD major
Definition: sdbtypes.h:30
BYTE * data
Definition: sdbtypes.h:27
TAGID stringtable
Definition: sdbtypes.h:28
DWORD minor
Definition: sdbtypes.h:31
DWORD size
Definition: sdbtypes.h:26
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
Definition: kse.h:92
Definition: btrfs_drv.h:1876
Definition: fs_rec.h:143
Definition: ecma_167.h:138
#define TAG_KSE_DATABASE
Definition: tag.h:130
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
uint16_t * LPWSTR
Definition: typedefs.h:56
#define NTAPI
Definition: typedefs.h:36
const char * PCSTR
Definition: typedefs.h:52
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ UCXENDPOINT _In_ PVOID Tag
Definition: ucxendpoint.h:325
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_NAME
Definition: vfat.h:553
_Must_inspect_result_ _In_ WDFDRIVER Driver
Definition: wdfcontrol.h:83
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2439
_Must_inspect_result_ _In_ WDFOBJECT _In_ CONST GUID * Guid
Definition: wdfobject.h:762
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36