1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 ModuleName: 6 7 MxGeneral.h 8 9 Abstract: 10 11 Mode agnostic definitions for general OS 12 functions used in framework code 13 14 See MxGeneralKm.h and MxGeneralUm.h for mode 15 specific implementations 16 17 Author: 18 19 20 21 Revision History: 22 23 24 25 --*/ 26 27 #pragma once 28 29 // 30 // Placeholder macro for a no-op 31 // 32 #define DO_NOTHING() (0) 33 34 // 35 // We need to make these static functions of the class 36 // to force common definition to apply to um and km versions 37 // 38 // If we don't do this, um and km definitions can diverge 39 // 40 class Mx 41 { 42 public: 43 44 // 45 // IsUM/IsKM don't change at runtime 46 // but defining them as functions makes it more convenient to check 47 // for UM/KM as compared to using ifdef's in certain places 48 // 49 // Since they are forceinlined and return a constant value, 50 // optimized code is no different than using an ifdef 51 // 52 // See FxPoolAllocator in WdfPool.cpp for example of such usage 53 // 54 __inline 55 static 56 BOOLEAN 57 IsUM( 58 ); 59 60 __inline 61 static 62 BOOLEAN 63 IsKM( 64 ); 65 66 __inline 67 static 68 MxThread 69 MxGetCurrentThread( 70 ); 71 72 __inline 73 static 74 MdEThread 75 GetCurrentEThread( 76 ); 77 78 NTSTATUS 79 static 80 MxTerminateCurrentThread( 81 __in NTSTATUS Status 82 ); 83 84 __inline 85 static 86 KIRQL 87 MxGetCurrentIrql( 88 ); 89 90 __drv_maxIRQL(HIGH_LEVEL) 91 __drv_raisesIRQL(NewIrql) 92 __inline 93 static 94 VOID 95 MxRaiseIrql( 96 __in KIRQL NewIrql, 97 __out __deref __drv_savesIRQL PKIRQL OldIrql 98 ); 99 100 __drv_maxIRQL(HIGH_LEVEL) 101 __inline 102 static 103 VOID 104 MxLowerIrql( 105 __in __drv_restoresIRQL __drv_nonConstant KIRQL NewIrql 106 ); 107 108 __inline 109 static 110 VOID 111 MxQueryTickCount( 112 __out PLARGE_INTEGER TickCount 113 ); 114 115 __inline 116 static 117 ULONG 118 MxQueryTimeIncrement( 119 ); 120 121 122 123 124 125 126 127 128 static 129 DECLSPEC_NORETURN 130 VOID 131 MxBugCheckEx( 132 __in ULONG BugCheckCode, 133 __in ULONG_PTR BugCheckParameter1, 134 __in ULONG_PTR BugCheckParameter2, 135 __in ULONG_PTR BugCheckParameter3, 136 __in ULONG_PTR BugCheckParameter4 137 ); 138 139 __inline 140 static 141 VOID 142 MxDbgBreakPoint( 143 ); 144 145 static 146 VOID 147 MxDbgPrint( 148 __drv_formatString(printf) 149 __in PCSTR DebugMessage, 150 ... 151 ); 152 153 __inline 154 static 155 VOID 156 MxAssert( 157 __in BOOLEAN Condition 158 ); 159 160 __inline 161 static 162 VOID 163 MxAssertMsg( 164 __in LPSTR Message, 165 __in BOOLEAN Condition 166 ); 167 168 _Acquires_lock_(_Global_critical_region_) 169 __inline 170 static 171 VOID 172 MxEnterCriticalRegion( 173 ); 174 175 _Releases_lock_(_Global_critical_region_) //implies _Requires_lock_held_(_Global_critical_region_) 176 __inline 177 static 178 VOID 179 MxLeaveCriticalRegion( 180 ); 181 182 __inline 183 static 184 VOID 185 MxDelayExecutionThread( 186 __in KPROCESSOR_MODE WaitMode, 187 __in BOOLEAN Alertable, 188 __in PLARGE_INTEGER Interval 189 ); 190 191 // 192 // Mode agnostic function to get address of a system function 193 // Should be used only for Rtl* functions applicable both to 194 // kernel mode and user mode 195 // 196 // User mode version is assumed to reside in ntdll.dll 197 // 198 // The argument type is MxFuncName so that it can be defined 199 // as LPCWSTR in kernel mode and LPCSTR in user mode 200 // which is what MmGetSystemRoutineAddress and GetProcAddress 201 // expect respectively 202 // 203 __inline 204 static 205 PVOID 206 MxGetSystemRoutineAddress( 207 __in MxFuncName FuncName 208 ); 209 210 __inline 211 static 212 VOID 213 MxReferenceObject( 214 __in PVOID Object 215 ); 216 217 __inline 218 static 219 VOID 220 MxDereferenceObject( 221 __in PVOID Object 222 ); 223 224 __inline 225 static 226 VOID 227 MxInitializeRemoveLock( 228 __in MdRemoveLock Lock, 229 __in ULONG AllocateTag, 230 __in ULONG MaxLockedMinutes, 231 __in ULONG HighWatermark 232 ); 233 234 __inline 235 static 236 NTSTATUS 237 MxAcquireRemoveLock( 238 __in MdRemoveLock RemoveLock, 239 __in_opt PVOID Tag 240 ); 241 242 __inline 243 static 244 VOID 245 MxReleaseRemoveLock( 246 __in MdRemoveLock RemoveLock, 247 __in PVOID Tag 248 ); 249 250 __inline 251 static 252 VOID 253 MxReleaseRemoveLockAndWait( 254 __in MdRemoveLock RemoveLock, 255 __in PVOID Tag 256 ); 257 258 __inline 259 static 260 BOOLEAN 261 MxHasEnoughRemainingThreadStack( 262 VOID 263 ); 264 265 266 _Releases_lock_(_Global_cancel_spin_lock_) //implies _Requires_lock_held_(_Global_cancel_spin_lock_) 267 __drv_requiresIRQL(DISPATCH_LEVEL) 268 __inline 269 static 270 VOID 271 ReleaseCancelSpinLock( 272 __in __drv_restoresIRQL __drv_useCancelIRQL KIRQL Irql 273 ); 274 275 __inline 276 static 277 NTSTATUS 278 CreateCallback( 279 __out PCALLBACK_OBJECT *CallbackObject, 280 __in POBJECT_ATTRIBUTES ObjectAttributes, 281 __in BOOLEAN Create, 282 __in BOOLEAN AllowMultipleCallbacks 283 ); 284 285 __inline 286 static 287 PVOID 288 RegisterCallback( 289 __in PCALLBACK_OBJECT CallbackObject, 290 __in MdCallbackFunction CallbackFunction, 291 __in PVOID CallbackContext 292 ); 293 294 __inline 295 static 296 VOID 297 UnregisterCallback( 298 __in PVOID CbRegistration 299 ); 300 301 static 302 VOID 303 MxGlobalInit( 304 VOID 305 ); 306 307 __inline 308 static 309 VOID 310 MxUnlockPages( 311 __in PMDL Mdl 312 ); 313 314 __inline 315 static 316 PVOID 317 MxGetSystemAddressForMdlSafe( 318 __inout PMDL Mdl, 319 __in ULONG Priority 320 ); 321 322 __inline 323 static 324 VOID 325 MxBuildMdlForNonPagedPool( 326 __inout PMDL Mdl 327 ); 328 329 __inline 330 static 331 PVOID 332 MxGetDriverObjectExtension( 333 __in MdDriverObject DriverObject, 334 __in PVOID ClientIdentificationAddress 335 ); 336 337 __inline 338 static 339 NTSTATUS 340 MxAllocateDriverObjectExtension( 341 _In_ MdDriverObject DriverObject, 342 _In_ PVOID ClientIdentificationAddress, 343 _In_ ULONG DriverObjectExtensionSize, 344 // When successful, this always allocates already-aliased memory. 345 _Post_ _At_(*DriverObjectExtension, _When_(return==0, 346 __drv_aliasesMem __drv_allocatesMem(Mem) _Post_notnull_)) 347 _When_(return == 0, _Outptr_result_bytebuffer_(DriverObjectExtensionSize)) 348 PVOID *DriverObjectExtension 349 ); 350 351 __inline 352 static 353 MdDeviceObject 354 MxGetAttachedDeviceReference( 355 __in MdDeviceObject DriverObject 356 ); 357 358 __inline 359 static 360 VOID 361 MxDeleteSymbolicLink( 362 __in PUNICODE_STRING Link 363 ); 364 365 __inline 366 static 367 VOID 368 MxDeleteNPagedLookasideList( 369 _In_ PNPAGED_LOOKASIDE_LIST LookasideList 370 ); 371 372 __inline 373 static 374 VOID 375 MxDeletePagedLookasideList( 376 _In_ PPAGED_LOOKASIDE_LIST LookasideList 377 ); 378 379 __inline 380 static 381 VOID 382 MxInitializeNPagedLookasideList( 383 _Out_ PNPAGED_LOOKASIDE_LIST Lookaside, 384 _In_opt_ PALLOCATE_FUNCTION Allocate, 385 _In_opt_ PFREE_FUNCTION Free, 386 _In_ ULONG Flags, 387 _In_ SIZE_T Size, 388 _In_ ULONG Tag, 389 _In_ USHORT Depth 390 ); 391 392 __inline 393 static 394 VOID 395 MxInitializePagedLookasideList( 396 _Out_ PPAGED_LOOKASIDE_LIST Lookaside, 397 _In_opt_ PALLOCATE_FUNCTION Allocate, 398 _In_opt_ PFREE_FUNCTION Free, 399 _In_ ULONG Flags, 400 _In_ SIZE_T Size, 401 _In_ ULONG Tag, 402 _In_ USHORT Depth 403 ); 404 405 __inline 406 static 407 VOID 408 MxDeleteDevice( 409 _In_ MdDeviceObject Device 410 ); 411 412 static 413 VOID 414 MxDetachDevice( 415 _Inout_ MdDeviceObject Device 416 ); 417 418 __inline 419 static 420 MdDeviceObject 421 MxAttachDeviceToDeviceStack( 422 _In_ MdDeviceObject SourceDevice, 423 _In_ MdDeviceObject TargetDevice 424 ); 425 426 __inline 427 static 428 NTSTATUS 429 MxCreateDeviceSecure( 430 _In_ MdDriverObject DriverObject, 431 _In_ ULONG DeviceExtensionSize, 432 _In_opt_ PUNICODE_STRING DeviceName, 433 _In_ DEVICE_TYPE DeviceType, 434 _In_ ULONG DeviceCharacteristics, 435 _In_ BOOLEAN Exclusive, 436 _In_ PCUNICODE_STRING DefaultSDDLString, 437 _In_opt_ LPCGUID DeviceClassGuid, 438 _Out_ MdDeviceObject *DeviceObject 439 ); 440 441 __inline 442 static 443 NTSTATUS 444 MxCreateDevice( 445 _In_ MdDriverObject DriverObject, 446 _In_ ULONG DeviceExtensionSize, 447 _In_opt_ PUNICODE_STRING DeviceName, 448 _In_ DEVICE_TYPE DeviceType, 449 _In_ ULONG DeviceCharacteristics, 450 _In_ BOOLEAN Exclusive, 451 _Out_ MdDeviceObject *DeviceObject 452 ); 453 454 __inline 455 static 456 NTSTATUS 457 MxCreateSymbolicLink( 458 _In_ PUNICODE_STRING SymbolicLinkName, 459 _In_ PUNICODE_STRING DeviceName 460 ); 461 462 __inline 463 static 464 VOID 465 MxFlushQueuedDpcs( 466 ); 467 468 __inline 469 static 470 NTSTATUS 471 MxOpenKey( 472 _Out_ PHANDLE KeyHandle, 473 _In_ ACCESS_MASK DesiredAccess, 474 _In_ POBJECT_ATTRIBUTES ObjectAttributes 475 ); 476 477 __inline 478 static 479 NTSTATUS 480 MxSetDeviceInterfaceState( 481 _In_ PUNICODE_STRING SymbolicLinkName, 482 _In_ BOOLEAN Enable 483 ); 484 485 __inline 486 static 487 NTSTATUS 488 MxRegisterDeviceInterface( 489 _In_ PDEVICE_OBJECT PhysicalDeviceObject, 490 _In_ const GUID *InterfaceClassGuid, 491 _In_opt_ PUNICODE_STRING ReferenceString, 492 _Out_ PUNICODE_STRING SymbolicLinkName 493 ); 494 495 __inline 496 static 497 NTSTATUS 498 MxDeleteKey( 499 _In_ HANDLE KeyHandle 500 ); 501 502 __inline 503 static 504 VOID 505 MxInitializeMdl( 506 _In_ PMDL MemoryDescriptorList, 507 _In_ PVOID BaseVa, 508 _In_ SIZE_T Length 509 ); 510 511 __inline 512 static 513 PVOID 514 MxGetMdlVirtualAddress( 515 _In_ PMDL Mdl 516 ); 517 518 __inline 519 static 520 VOID 521 MxBuildPartialMdl( 522 _In_ PMDL SourceMdl, 523 _Inout_ PMDL TargetMdl, 524 _In_ PVOID VirtualAddress, 525 _In_ ULONG Length 526 ); 527 528 __inline 529 static 530 VOID 531 MxQuerySystemTime( 532 _Out_ PLARGE_INTEGER CurrentTime 533 ); 534 535 __inline 536 static 537 NTSTATUS 538 MxSetValueKey( 539 _In_ HANDLE KeyHandle, 540 _In_ PUNICODE_STRING ValueName, 541 _In_opt_ ULONG TitleIndex, 542 _In_ ULONG Type, 543 _In_opt_ PVOID Data, 544 _In_ ULONG DataSize 545 ); 546 547 __inline 548 static 549 NTSTATUS 550 MxQueryValueKey( 551 _In_ HANDLE KeyHandle, 552 _In_ PUNICODE_STRING ValueName, 553 _In_ KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, 554 _Out_opt_ PVOID KeyValueInformation, 555 _In_ ULONG Length, 556 _Out_ PULONG ResultLength 557 ); 558 __inline 559 static 560 NTSTATUS 561 MxReferenceObjectByHandle( 562 __in HANDLE Handle, 563 __in ACCESS_MASK DesiredAccess, 564 __in_opt POBJECT_TYPE ObjectType, 565 __in KPROCESSOR_MODE AccessMode, 566 __out PVOID *Object, 567 __out_opt POBJECT_HANDLE_INFORMATION HandleInformation 568 ); 569 570 __inline 571 static 572 NTSTATUS 573 MxUnRegisterPlugPlayNotification( 574 __in __drv_freesMem(Pool) PVOID NotificationEntry 575 ); 576 577 __inline 578 static 579 NTSTATUS 580 MxClose ( 581 __in HANDLE Handle 582 ); 583 584 __inline 585 static 586 KIRQL 587 MxAcquireInterruptSpinLock( 588 _Inout_ PKINTERRUPT Interrupt 589 ); 590 591 __inline 592 static 593 VOID 594 MxReleaseInterruptSpinLock( 595 _Inout_ PKINTERRUPT Interrupt, 596 _In_ KIRQL OldIrql 597 ); 598 599 __inline 600 static 601 BOOLEAN 602 MxInsertQueueDpc( 603 __inout PRKDPC Dpc, 604 __in_opt PVOID SystemArgument1, 605 __in_opt PVOID SystemArgument2 606 ); 607 }; 608