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