[NTOSKRNL/FORMATTING]
[reactos.git] / reactos / ntoskrnl / mm / ARM3 / drvmgmt.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: ntoskrnl/mm/ARM3/drvmgmt.c
5 * PURPOSE: ARM Memory Manager Driver Management
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 #define MODULE_INVOLVED_IN_ARM3
16 #include "../ARM3/miarm.h"
17
18 /* GLOBALS *******************************************************************/
19
20 MM_DRIVER_VERIFIER_DATA MmVerifierData;
21 LIST_ENTRY MiVerifierDriverAddedThunkListHead;
22 ULONG MiActiveVerifierThunks;
23 WCHAR MmVerifyDriverBuffer[512] = {0};
24 ULONG MmVerifyDriverBufferLength = sizeof(MmVerifyDriverBuffer);
25 ULONG MmVerifyDriverBufferType = REG_NONE;
26 ULONG MmVerifyDriverLevel = -1;
27 PVOID MmTriageActionTaken;
28 PVOID KernelVerifier;
29
30 /* PUBLIC FUNCTIONS ***********************************************************/
31
32 /*
33 * @unimplemented
34 */
35 VOID
36 NTAPI
37 MmUnlockPageableImageSection(IN PVOID ImageSectionHandle)
38 {
39 UNIMPLEMENTED;
40 }
41
42 /*
43 * @unimplemented
44 */
45 VOID
46 NTAPI
47 MmLockPageableSectionByHandle(IN PVOID ImageSectionHandle)
48 {
49 UNIMPLEMENTED;
50 }
51
52 /*
53 * @unimplemented
54 */
55 PVOID
56 NTAPI
57 MmLockPageableDataSection(IN PVOID AddressWithinSection)
58 {
59 //
60 // We should just find the section and call MmLockPageableSectionByHandle
61 //
62 static BOOLEAN Warn; if (!Warn++) UNIMPLEMENTED;
63 return AddressWithinSection;
64 }
65
66 /*
67 * @unimplemented
68 */
69 ULONG
70 NTAPI
71 MmTrimAllSystemPageableMemory(IN ULONG PurgeTransitionList)
72 {
73 UNIMPLEMENTED;
74 return 0;
75 }
76
77 /*
78 * @implemented
79 */
80 NTSTATUS
81 NTAPI
82 MmAddVerifierThunks(IN PVOID ThunkBuffer,
83 IN ULONG ThunkBufferSize)
84 {
85 PDRIVER_VERIFIER_THUNK_PAIRS ThunkTable;
86 ULONG ThunkCount;
87 PDRIVER_SPECIFIED_VERIFIER_THUNKS DriverThunks;
88 PLDR_DATA_TABLE_ENTRY LdrEntry;
89 PVOID ModuleBase, ModuleEnd;
90 ULONG i;
91 NTSTATUS Status = STATUS_SUCCESS;
92 PAGED_CODE();
93
94 //
95 // Make sure the driver verifier is initialized
96 //
97 if (!MiVerifierDriverAddedThunkListHead.Flink) return STATUS_NOT_SUPPORTED;
98
99 //
100 // Get the thunk pairs and count them
101 //
102 ThunkCount = ThunkBufferSize / sizeof(DRIVER_VERIFIER_THUNK_PAIRS);
103 if (!ThunkCount) return STATUS_INVALID_PARAMETER_1;
104
105 //
106 // Now allocate our own thunk table
107 //
108 DriverThunks = ExAllocatePoolWithTag(PagedPool,
109 sizeof(*DriverThunks) +
110 ThunkCount *
111 sizeof(DRIVER_VERIFIER_THUNK_PAIRS),
112 'tVmM');
113 if (!DriverThunks) return STATUS_INSUFFICIENT_RESOURCES;
114
115 //
116 // Now copy the driver-fed part
117 //
118 ThunkTable = (PDRIVER_VERIFIER_THUNK_PAIRS)(DriverThunks + 1);
119 RtlCopyMemory(ThunkTable,
120 ThunkBuffer,
121 ThunkCount * sizeof(DRIVER_VERIFIER_THUNK_PAIRS));
122
123 //
124 // Acquire the system load lock
125 //
126 KeEnterCriticalRegion();
127 KeWaitForSingleObject(&MmSystemLoadLock,
128 WrVirtualMemory,
129 KernelMode,
130 FALSE,
131 NULL);
132
133 //
134 // Get the loader entry
135 //
136 LdrEntry = MiLookupDataTableEntry(ThunkTable->PristineRoutine);
137 if (!LdrEntry)
138 {
139 //
140 // Fail
141 //
142 Status = STATUS_INVALID_PARAMETER_2;
143 goto Cleanup;
144 }
145
146 //
147 // Get driver base and end
148 //
149 ModuleBase = LdrEntry->DllBase;
150 ModuleEnd = (PVOID)((ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage);
151
152 //
153 // Don't allow hooking the kernel or HAL
154 //
155 if (ModuleBase < (PVOID)(KSEG0_BASE + MmBootImageSize))
156 {
157 //
158 // Fail
159 //
160 Status = STATUS_INVALID_PARAMETER_2;
161 goto Cleanup;
162 }
163
164 //
165 // Loop all the thunks
166 //
167 for (i = 0; i < ThunkCount; i++)
168 {
169 //
170 // Make sure it's in the driver
171 //
172 if (((ULONG_PTR)ThunkTable->PristineRoutine < (ULONG_PTR)ModuleBase) ||
173 ((ULONG_PTR)ThunkTable->PristineRoutine >= (ULONG_PTR)ModuleEnd))
174 {
175 //
176 // Nope, fail
177 //
178 Status = STATUS_INVALID_PARAMETER_2;
179 goto Cleanup;
180 }
181 }
182
183 //
184 // Otherwise, add this entry
185 //
186 DriverThunks->DataTableEntry = LdrEntry;
187 DriverThunks->NumberOfThunks = ThunkCount;
188 MiActiveVerifierThunks++;
189 InsertTailList(&MiVerifierDriverAddedThunkListHead,
190 &DriverThunks->ListEntry);
191 DriverThunks = NULL;
192
193 Cleanup:
194 //
195 // Release the lock
196 //
197 KeReleaseMutant(&MmSystemLoadLock, 1, FALSE, FALSE);
198 KeLeaveCriticalRegion();
199
200 //
201 // Free the table if we failed and return status
202 //
203 if (DriverThunks) ExFreePool(DriverThunks);
204 return Status;
205 }
206
207 /*
208 * @implemented
209 */
210 LOGICAL
211 NTAPI
212 MmIsDriverVerifying(IN PDRIVER_OBJECT DriverObject)
213 {
214 PLDR_DATA_TABLE_ENTRY LdrEntry;
215
216 //
217 // Get the loader entry
218 //
219 LdrEntry = (PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection;
220 if (!LdrEntry) return FALSE;
221
222 //
223 // Check if we're verifying or not
224 //
225 return (LdrEntry->Flags & LDRP_IMAGE_VERIFYING) ? TRUE: FALSE;
226 }
227
228 /*
229 * @implemented
230 */
231 NTSTATUS
232 NTAPI
233 MmIsVerifierEnabled(OUT PULONG VerifierFlags)
234 {
235 //
236 // Check if we've actually added anything to the list
237 //
238 if (MiVerifierDriverAddedThunkListHead.Flink)
239 {
240 //
241 // We have, read the verifier level
242 //
243 *VerifierFlags = MmVerifierData.Level;
244 return STATUS_SUCCESS;
245 }
246
247 //
248 // Otherwise, we're disabled
249 //
250 *VerifierFlags = 0;
251 return STATUS_NOT_SUPPORTED;
252 }
253
254 /* EOF */