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
9 /* INCLUDES *******************************************************************/
15 #line 15 "ARMĀ³::DRVMGMT"
16 #define MODULE_INVOLVED_IN_ARM3
17 #include "../ARM3/miarm.h"
19 /* GLOBALS *******************************************************************/
21 MM_DRIVER_VERIFIER_DATA MmVerifierData
;
22 LIST_ENTRY MiVerifierDriverAddedThunkListHead
;
23 ULONG MiActiveVerifierThunks
;
25 /* PRIVATE FUNCTIONS *********************************************************/
29 MiLookupDataTableEntry(IN PVOID Address
)
31 PLDR_DATA_TABLE_ENTRY LdrEntry
, FoundEntry
= NULL
;
32 PLIST_ENTRY NextEntry
;
38 NextEntry
= PsLoadedModuleList
.Flink
;
42 // Get the loader entry
44 LdrEntry
= CONTAINING_RECORD(NextEntry
,
49 // Check if the address matches
51 if ((Address
>= LdrEntry
->DllBase
) &&
52 (Address
< (PVOID
)((ULONG_PTR
)LdrEntry
->DllBase
+
53 LdrEntry
->SizeOfImage
)))
58 FoundEntry
= LdrEntry
;
65 NextEntry
= NextEntry
->Flink
;
66 } while(NextEntry
!= &PsLoadedModuleList
);
74 /* PUBLIC FUNCTIONS ***********************************************************/
81 MmUnlockPageableImageSection(IN PVOID ImageSectionHandle
)
91 MmLockPageableSectionByHandle(IN PVOID ImageSectionHandle
)
101 MmLockPageableDataSection(IN PVOID AddressWithinSection
)
104 // We should just find the section and call MmLockPageableSectionByHandle
107 return AddressWithinSection
;
115 MmPageEntireDriver(IN PVOID AddressWithinSection
)
117 //PMMPTE StartPte, EndPte;
118 PLDR_DATA_TABLE_ENTRY LdrEntry
;
122 // Get the loader entry
124 LdrEntry
= MiLookupDataTableEntry(AddressWithinSection
);
125 if (!LdrEntry
) return NULL
;
128 // Check if paging of kernel mode is disabled or if the driver is mapped as
131 if ((MmDisablePagingExecutive
& 0x1) || (LdrEntry
->SectionPointer
))
134 // Don't do anything, just return the base address
136 return LdrEntry
->DllBase
;
140 // Wait for active DPCs to finish before we page out the driver
145 // Get the PTE range for the whole driver image
147 //StartPte = MiGetPteAddress(LdrEntry->DllBase);
148 //EndPte = MiGetPteAddress(LdrEntry->DllBase +
149 // LdrEntry->SizeOfImage);
152 // Enable paging for the PTE range
154 //MiSetPagingOfDriver(StartPte, EndPte);
157 // Return the base address
159 return LdrEntry
->DllBase
;
167 MmResetDriverPaging(IN PVOID AddressWithinSection
)
177 MmTrimAllSystemPageableMemory(IN ULONG PurgeTransitionList
)
188 MmAddVerifierThunks(IN PVOID ThunkBuffer
,
189 IN ULONG ThunkBufferSize
)
191 PDRIVER_VERIFIER_THUNK_PAIRS ThunkTable
;
193 PDRIVER_SPECIFIED_VERIFIER_THUNKS DriverThunks
;
194 PLDR_DATA_TABLE_ENTRY LdrEntry
;
195 PVOID ModuleBase
, ModuleEnd
;
197 NTSTATUS Status
= STATUS_SUCCESS
;
201 // Make sure the driver verifier is initialized
203 if (!MiVerifierDriverAddedThunkListHead
.Flink
) return STATUS_NOT_SUPPORTED
;
206 // Get the thunk pairs and count them
208 ThunkCount
= ThunkBufferSize
/ sizeof(DRIVER_VERIFIER_THUNK_PAIRS
);
209 if (!ThunkCount
) return STATUS_INVALID_PARAMETER_1
;
212 // Now allocate our own thunk table
214 DriverThunks
= ExAllocatePoolWithTag(PagedPool
,
215 sizeof(*DriverThunks
) +
217 sizeof(DRIVER_VERIFIER_THUNK_PAIRS
),
219 if (!DriverThunks
) return STATUS_INSUFFICIENT_RESOURCES
;
222 // Now copy the driver-fed part
224 ThunkTable
= (PDRIVER_VERIFIER_THUNK_PAIRS
)(DriverThunks
+ 1);
225 RtlCopyMemory(ThunkTable
,
227 ThunkCount
* sizeof(DRIVER_VERIFIER_THUNK_PAIRS
));
230 // Acquire the system load lock
232 KeEnterCriticalRegion();
233 KeWaitForSingleObject(&MmSystemLoadLock
,
240 // Get the loader entry
242 LdrEntry
= MiLookupDataTableEntry(ThunkTable
->PristineRoutine
);
248 Status
= STATUS_INVALID_PARAMETER_2
;
253 // Get driver base and end
255 ModuleBase
= LdrEntry
->DllBase
;
256 ModuleEnd
= (PVOID
)((ULONG_PTR
)LdrEntry
->DllBase
+ LdrEntry
->SizeOfImage
);
259 // Don't allow hooking the kernel or HAL
261 if (ModuleBase
< (PVOID
)(KSEG0_BASE
+ MmBootImageSize
))
266 Status
= STATUS_INVALID_PARAMETER_2
;
271 // Loop all the thunks
273 for (i
= 0; i
< ThunkCount
; i
++)
276 // Make sure it's in the driver
278 if (((ULONG_PTR
)ThunkTable
->PristineRoutine
< (ULONG_PTR
)ModuleBase
) ||
279 ((ULONG_PTR
)ThunkTable
->PristineRoutine
>= (ULONG_PTR
)ModuleEnd
))
284 Status
= STATUS_INVALID_PARAMETER_2
;
290 // Otherwise, add this entry
292 DriverThunks
->DataTableEntry
= LdrEntry
;
293 DriverThunks
->NumberOfThunks
= ThunkCount
;
294 MiActiveVerifierThunks
++;
295 InsertTailList(&MiVerifierDriverAddedThunkListHead
,
296 &DriverThunks
->ListEntry
);
303 KeReleaseMutant(&MmSystemLoadLock
, 1, FALSE
, FALSE
);
304 KeLeaveCriticalRegion();
307 // Free the table if we failed and return status
309 if (DriverThunks
) ExFreePool(DriverThunks
);
318 MmIsDriverVerifying(IN PDRIVER_OBJECT DriverObject
)
320 PLDR_DATA_TABLE_ENTRY LdrEntry
;
323 // Get the loader entry
325 LdrEntry
= (PLDR_DATA_TABLE_ENTRY
)DriverObject
->DriverSection
;
326 if (!LdrEntry
) return FALSE
;
329 // Check if we're verifying or not
331 return (LdrEntry
->Flags
& LDRP_IMAGE_VERIFYING
) ? TRUE
: FALSE
;
339 MmIsVerifierEnabled(OUT PULONG VerifierFlags
)
342 // Check if we've actually added anything to the list
344 if (MiVerifierDriverAddedThunkListHead
.Flink
)
347 // We have, read the verifier level
349 *VerifierFlags
= MmVerifierData
.Level
;
350 return STATUS_SUCCESS
;
354 // Otherwise, we're disabled
357 return STATUS_NOT_SUPPORTED
;