xref: /reactos/ntoskrnl/mm/ARM3/drvmgmt.c (revision 25720d75)
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     static BOOLEAN Warn; if (!Warn++) 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 */
256