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 25 /* PRIVATE FUNCTIONS *********************************************************/ 26 27 PLDR_DATA_TABLE_ENTRY 28 NTAPI 29 MiLookupDataTableEntry(IN PVOID Address) 30 { 31 PLDR_DATA_TABLE_ENTRY LdrEntry, FoundEntry = NULL; 32 PLIST_ENTRY NextEntry; 33 PAGED_CODE(); 34 35 // 36 // Loop entries 37 // 38 NextEntry = PsLoadedModuleList.Flink; 39 do 40 { 41 // 42 // Get the loader entry 43 // 44 LdrEntry = CONTAINING_RECORD(NextEntry, 45 LDR_DATA_TABLE_ENTRY, 46 InLoadOrderLinks); 47 48 // 49 // Check if the address matches 50 // 51 if ((Address >= LdrEntry->DllBase) && 52 (Address < (PVOID)((ULONG_PTR)LdrEntry->DllBase + 53 LdrEntry->SizeOfImage))) 54 { 55 // 56 // Found a match 57 // 58 FoundEntry = LdrEntry; 59 break; 60 } 61 62 // 63 // Move on 64 // 65 NextEntry = NextEntry->Flink; 66 } while(NextEntry != &PsLoadedModuleList); 67 68 // 69 // Return the entry 70 // 71 return FoundEntry; 72 } 73 74 /* PUBLIC FUNCTIONS ***********************************************************/ 75 76 /* 77 * @unimplemented 78 */ 79 VOID 80 NTAPI 81 MmUnlockPageableImageSection(IN PVOID ImageSectionHandle) 82 { 83 UNIMPLEMENTED; 84 } 85 86 /* 87 * @unimplemented 88 */ 89 VOID 90 NTAPI 91 MmLockPageableSectionByHandle(IN PVOID ImageSectionHandle) 92 { 93 UNIMPLEMENTED; 94 } 95 96 /* 97 * @unimplemented 98 */ 99 PVOID 100 NTAPI 101 MmLockPageableDataSection(IN PVOID AddressWithinSection) 102 { 103 // 104 // We should just find the section and call MmLockPageableSectionByHandle 105 // 106 UNIMPLEMENTED; 107 return AddressWithinSection; 108 } 109 110 /* 111 * @unimplemented 112 */ 113 PVOID 114 NTAPI 115 MmPageEntireDriver(IN PVOID AddressWithinSection) 116 { 117 //PMMPTE StartPte, EndPte; 118 PLDR_DATA_TABLE_ENTRY LdrEntry; 119 PAGED_CODE(); 120 121 // 122 // Get the loader entry 123 // 124 LdrEntry = MiLookupDataTableEntry(AddressWithinSection); 125 if (!LdrEntry) return NULL; 126 127 // 128 // Check if paging of kernel mode is disabled or if the driver is mapped as 129 // an image 130 // 131 if ((MmDisablePagingExecutive & 0x1) || (LdrEntry->SectionPointer)) 132 { 133 // 134 // Don't do anything, just return the base address 135 // 136 return LdrEntry->DllBase; 137 } 138 139 // 140 // Wait for active DPCs to finish before we page out the driver 141 // 142 KeFlushQueuedDpcs(); 143 144 // 145 // Get the PTE range for the whole driver image 146 // 147 //StartPte = MiGetPteAddress(LdrEntry->DllBase); 148 //EndPte = MiGetPteAddress(LdrEntry->DllBase + 149 // LdrEntry->SizeOfImage); 150 151 // 152 // Enable paging for the PTE range 153 // 154 //MiSetPagingOfDriver(StartPte, EndPte); 155 156 // 157 // Return the base address 158 // 159 return LdrEntry->DllBase; 160 } 161 162 /* 163 * @unimplemented 164 */ 165 VOID 166 NTAPI 167 MmResetDriverPaging(IN PVOID AddressWithinSection) 168 { 169 UNIMPLEMENTED; 170 } 171 172 /* 173 * @unimplemented 174 */ 175 ULONG 176 NTAPI 177 MmTrimAllSystemPageableMemory(IN ULONG PurgeTransitionList) 178 { 179 UNIMPLEMENTED; 180 return 0; 181 } 182 183 /* 184 * @implemented 185 */ 186 NTSTATUS 187 NTAPI 188 MmAddVerifierThunks(IN PVOID ThunkBuffer, 189 IN ULONG ThunkBufferSize) 190 { 191 PDRIVER_VERIFIER_THUNK_PAIRS ThunkTable; 192 ULONG ThunkCount; 193 PDRIVER_SPECIFIED_VERIFIER_THUNKS DriverThunks; 194 PLDR_DATA_TABLE_ENTRY LdrEntry; 195 PVOID ModuleBase, ModuleEnd; 196 ULONG i; 197 NTSTATUS Status = STATUS_SUCCESS; 198 PAGED_CODE(); 199 200 // 201 // Make sure the driver verifier is initialized 202 // 203 if (!MiVerifierDriverAddedThunkListHead.Flink) return STATUS_NOT_SUPPORTED; 204 205 // 206 // Get the thunk pairs and count them 207 // 208 ThunkCount = ThunkBufferSize / sizeof(DRIVER_VERIFIER_THUNK_PAIRS); 209 if (!ThunkCount) return STATUS_INVALID_PARAMETER_1; 210 211 // 212 // Now allocate our own thunk table 213 // 214 DriverThunks = ExAllocatePoolWithTag(PagedPool, 215 sizeof(*DriverThunks) + 216 ThunkCount * 217 sizeof(DRIVER_VERIFIER_THUNK_PAIRS), 218 'tVmM'); 219 if (!DriverThunks) return STATUS_INSUFFICIENT_RESOURCES; 220 221 // 222 // Now copy the driver-fed part 223 // 224 ThunkTable = (PDRIVER_VERIFIER_THUNK_PAIRS)(DriverThunks + 1); 225 RtlCopyMemory(ThunkTable, 226 ThunkBuffer, 227 ThunkCount * sizeof(DRIVER_VERIFIER_THUNK_PAIRS)); 228 229 // 230 // Acquire the system load lock 231 // 232 KeEnterCriticalRegion(); 233 KeWaitForSingleObject(&MmSystemLoadLock, 234 WrVirtualMemory, 235 KernelMode, 236 FALSE, 237 NULL); 238 239 // 240 // Get the loader entry 241 // 242 LdrEntry = MiLookupDataTableEntry(ThunkTable->PristineRoutine); 243 if (!LdrEntry) 244 { 245 // 246 // Fail 247 // 248 Status = STATUS_INVALID_PARAMETER_2; 249 goto Cleanup; 250 } 251 252 // 253 // Get driver base and end 254 // 255 ModuleBase = LdrEntry->DllBase; 256 ModuleEnd = (PVOID)((ULONG_PTR)LdrEntry->DllBase + LdrEntry->SizeOfImage); 257 258 // 259 // Don't allow hooking the kernel or HAL 260 // 261 if (ModuleBase < (PVOID)(KSEG0_BASE + MmBootImageSize)) 262 { 263 // 264 // Fail 265 // 266 Status = STATUS_INVALID_PARAMETER_2; 267 goto Cleanup; 268 } 269 270 // 271 // Loop all the thunks 272 // 273 for (i = 0; i < ThunkCount; i++) 274 { 275 // 276 // Make sure it's in the driver 277 // 278 if (((ULONG_PTR)ThunkTable->PristineRoutine < (ULONG_PTR)ModuleBase) || 279 ((ULONG_PTR)ThunkTable->PristineRoutine >= (ULONG_PTR)ModuleEnd)) 280 { 281 // 282 // Nope, fail 283 // 284 Status = STATUS_INVALID_PARAMETER_2; 285 goto Cleanup; 286 } 287 } 288 289 // 290 // Otherwise, add this entry 291 // 292 DriverThunks->DataTableEntry = LdrEntry; 293 DriverThunks->NumberOfThunks = ThunkCount; 294 MiActiveVerifierThunks++; 295 InsertTailList(&MiVerifierDriverAddedThunkListHead, 296 &DriverThunks->ListEntry); 297 DriverThunks = NULL; 298 299 Cleanup: 300 // 301 // Release the lock 302 // 303 KeReleaseMutant(&MmSystemLoadLock, 1, FALSE, FALSE); 304 KeLeaveCriticalRegion(); 305 306 // 307 // Free the table if we failed and return status 308 // 309 if (DriverThunks) ExFreePool(DriverThunks); 310 return Status; 311 } 312 313 /* 314 * @implemented 315 */ 316 LOGICAL 317 NTAPI 318 MmIsDriverVerifying(IN PDRIVER_OBJECT DriverObject) 319 { 320 PLDR_DATA_TABLE_ENTRY LdrEntry; 321 322 // 323 // Get the loader entry 324 // 325 LdrEntry = (PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection; 326 if (!LdrEntry) return FALSE; 327 328 // 329 // Check if we're verifying or not 330 // 331 return (LdrEntry->Flags & LDRP_IMAGE_VERIFYING) ? TRUE: FALSE; 332 } 333 334 /* 335 * @implemented 336 */ 337 NTSTATUS 338 NTAPI 339 MmIsVerifierEnabled(OUT PULONG VerifierFlags) 340 { 341 // 342 // Check if we've actually added anything to the list 343 // 344 if (MiVerifierDriverAddedThunkListHead.Flink) 345 { 346 // 347 // We have, read the verifier level 348 // 349 *VerifierFlags = MmVerifierData.Level; 350 return STATUS_SUCCESS; 351 } 352 353 // 354 // Otherwise, we're disabled 355 // 356 *VerifierFlags = 0; 357 return STATUS_NOT_SUPPORTED; 358 } 359 360 /* EOF */ 361