1 /*++ 2 3 Copyright (c) Microsoft Corporation 4 5 Module Name: 6 7 FxGlobalsKm.h 8 9 Abstract: 10 11 This module contains kernel-mode specific globals definitions 12 for the frameworks. 13 14 For common definitions common between km and um please see 15 FxGlobals.h 16 17 Author: 18 19 20 21 Environment: 22 23 Kernel mode only 24 25 Revision History: 26 27 28 --*/ 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 extern PCHAR WdfLdrType; 34 35 #define WDF_LDR_STATIC_TYPE_STR "WdfStatic" 36 37 // forward definitions 38 typedef struct _FX_DRIVER_GLOBALS *PFX_DRIVER_GLOBALS; 39 typedef struct _FX_DUMP_DRIVER_INFO_ENTRY *PFX_DUMP_DRIVER_INFO_ENTRY; 40 41 struct FxMdlDebugInfo { 42 PMDL Mdl; 43 FxObject* Owner; 44 PVOID Caller; 45 }; 46 47 #define NUM_MDLS_IN_INFO (16) 48 49 struct FxAllocatedMdls { 50 FxMdlDebugInfo Info[NUM_MDLS_IN_INFO]; 51 ULONG Count; 52 struct FxAllocatedMdls* Next; 53 }; 54 55 #define DDI_ENTRY_IMPERSONATION_OK() 56 #define DDI_ENTRY() 57 58 typedef 59 BOOLEAN 60 (STDCALL *PFN_KD_REFRESH)( 61 ); 62 63 typedef 64 VOID 65 (STDCALL *PFN_KE_FLUSH_QUEUED_DPCS)( 66 VOID 67 ); 68 69 typedef 70 NTSTATUS 71 (STDCALL *PFN_IO_SET_COMPLETION_ROUTINE_EX)( 72 __in PDEVICE_OBJECT DeviceObject, 73 __in PIRP Irp, 74 __in PIO_COMPLETION_ROUTINE CompletionRoutine, 75 __in PVOID Context, 76 __in BOOLEAN InvokeOnSuccess, 77 __in BOOLEAN InvokeOnError, 78 __in BOOLEAN InvokeOnCancel 79 ); 80 81 typedef 82 BOOLEAN 83 (STDCALL *PFN_KE_REGISTER_BUGCHECK_REASON_CALLBACK) ( 84 __in PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord, 85 __in PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine, 86 __in KBUGCHECK_CALLBACK_REASON Reason, 87 __in PUCHAR Component 88 ); 89 90 typedef 91 BOOLEAN 92 (STDCALL *PFN_KE_DEREGISTER_BUGCHECK_REASON_CALLBACK) ( 93 __in PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecords 94 ); 95 96 typedef 97 NTSTATUS 98 (STDCALL *PFN_IO_CONNECT_INTERRUPT_EX)( 99 __inout PIO_CONNECT_INTERRUPT_PARAMETERS Parameters 100 ); 101 102 typedef 103 NTSTATUS 104 (STDCALL *PFN_IO_DISCONNECT_INTERRUPT_EX)( 105 __in PIO_DISCONNECT_INTERRUPT_PARAMETERS Parameters 106 ); 107 108 typedef 109 NTSTATUS 110 (STDCALL *PFN_IO_CONNECT_INTERRUPT)( 111 __out PKINTERRUPT *InterruptObject, 112 __in PKSERVICE_ROUTINE ServiceRoutine, 113 __in_opt PVOID ServiceContext, 114 __in_opt PKSPIN_LOCK SpinLock, 115 __in ULONG Vector, 116 __in KIRQL Irql, 117 __in KIRQL SynchronizeIrql, 118 __in KINTERRUPT_MODE InterruptMode, 119 __in BOOLEAN ShareVector, 120 __in KAFFINITY ProcessorEnableMask, 121 __in BOOLEAN FloatingSave 122 ); 123 124 typedef 125 VOID 126 (STDCALL *PFN_IO_DISCONNECT_INTERRUPT)( 127 __in PKINTERRUPT InterruptObject 128 ); 129 130 typedef 131 KIRQL 132 (FASTCALL *PFN_KF_RAISE_IRQL) ( 133 __in KIRQL NewIrql 134 ); 135 136 typedef 137 VOID 138 (FASTCALL *PFN_KF_LOWER_IRQL) ( 139 __in KIRQL NewIrql 140 ); 141 142 typedef 143 PSLIST_ENTRY 144 (FASTCALL *PFN_INTERLOCKED_POP_ENTRY_SLIST)( 145 __inout PSLIST_HEADER ListHead 146 ); 147 148 typedef 149 PSLIST_ENTRY 150 (FASTCALL *PFN_INTERLOCKED_PUSH_ENTRY_SLIST)( 151 __inout PSLIST_HEADER ListHead, 152 __inout PSLIST_ENTRY ListEntry 153 ); 154 155 typedef 156 BOOLEAN 157 (STDCALL *PFN_PO_GET_SYSTEM_WAKE)( 158 __in PIRP Irp 159 ); 160 161 typedef 162 VOID 163 (STDCALL *PFN_PO_SET_SYSTEM_WAKE)( 164 __inout PIRP Irp 165 ); 166 167 typedef 168 KAFFINITY 169 (STDCALL *PFN_KE_QUERY_ACTIVE_PROCESSORS)( 170 VOID 171 ); 172 173 typedef 174 VOID 175 (STDCALL *PFN_KE_SET_TARGET_PROCESSOR_DPC)( 176 __in PRKDPC Dpc, 177 __in CCHAR Number 178 ); 179 180 typedef 181 BOOLEAN 182 (STDCALL *PFN_KE_SET_COALESCABLE_TIMER)( 183 __inout PKTIMER Timer, 184 __in LARGE_INTEGER DueTime, 185 __in ULONG Period, 186 __in ULONG TolerableDelay, 187 __in_opt PKDPC Dpc 188 ); 189 190 typedef 191 ULONG 192 (STDCALL *PFN_KE_GET_CURRENT_PROCESSOR_NUMBER)( 193 VOID 194 ); 195 196 typedef 197 ULONG 198 (STDCALL *PFN_KE_GET_CURRENT_PROCESSOR_NUMBER_EX)( 199 __out_opt PPROCESSOR_NUMBER ProcNumber 200 ); 201 202 typedef 203 ULONG 204 (STDCALL *PFN_KE_QUERY_MAXIMUM_PROCESSOR_COUNT_EX)( 205 __in USHORT GroupNumber 206 ); 207 208 typedef 209 ULONG 210 (STDCALL *PFN_KE_QUERY_MAXIMUM_PROCESSOR_COUNT)( 211 VOID 212 ); 213 214 typedef 215 BOOLEAN 216 (STDCALL *PFN_KE_ARE_APCS_DISABLED)( 217 VOID 218 ); 219 220 typedef 221 ULONG 222 (STDCALL *PFN_KE_GET_RECOMMENDED_SHARED_DATA_ALIGNMENT)( 223 VOID 224 ); 225 226 typedef 227 NTSTATUS 228 (STDCALL *PFN_IO_UNREGISTER_PLUGPLAY_NOTIFICATION_EX)( 229 __in PVOID NotificationEntry 230 ); 231 232 typedef 233 NTSTATUS 234 (STDCALL *PFN_POX_REGISTER_DEVICE) ( 235 __in MdDeviceObject Pdo, 236 __in PPO_FX_DEVICE PoxDevice, 237 __out POHANDLE * Handle 238 ); 239 240 typedef 241 VOID 242 (STDCALL *PFN_POX_START_DEVICE_POWER_MANAGEMENT) ( 243 __in POHANDLE Handle 244 ); 245 246 typedef 247 VOID 248 (STDCALL *PFN_POX_UNREGISTER_DEVICE) ( 249 __in POHANDLE Handle 250 ); 251 252 typedef 253 VOID 254 (STDCALL *PFN_POX_ACTIVATE_COMPONENT) ( 255 __in POHANDLE Handle, 256 __in ULONG Component, 257 __in ULONG Flags 258 ); 259 260 typedef 261 VOID 262 (STDCALL *PFN_POX_IDLE_COMPONENT) ( 263 __in POHANDLE Handle, 264 __in ULONG Component, 265 __in ULONG Flags 266 ); 267 268 typedef 269 VOID 270 (STDCALL *PFN_POX_REPORT_DEVICE_POWERED_ON) ( 271 __in POHANDLE Handle 272 ); 273 274 typedef 275 VOID 276 (STDCALL *PFN_POX_COMPLETE_IDLE_STATE) ( 277 __in POHANDLE Handle, 278 __in ULONG Component 279 ); 280 281 typedef 282 VOID 283 (STDCALL *PFN_POX_COMPLETE_IDLE_CONDITION) ( 284 __in POHANDLE Handle, 285 __in ULONG Component 286 ); 287 288 typedef 289 VOID 290 (STDCALL *PFN_POX_COMPLETE_DEVICE_POWER_NOT_REQUIRED) ( 291 __in POHANDLE Handle 292 ); 293 294 typedef 295 VOID 296 (STDCALL *PFN_POX_SET_DEVICE_IDLE_TIMEOUT) ( 297 __in POHANDLE Handle, 298 __in ULONGLONG IdleTimeout 299 ); 300 301 typedef 302 VOID 303 (STDCALL *PFN_IO_REPORT_INTERRUPT_ACTIVE) ( 304 _In_ PIO_REPORT_INTERRUPT_ACTIVE_STATE_PARAMETERS Parameters 305 ); 306 307 typedef 308 VOID 309 (STDCALL *PFN_IO_REPORT_INTERRUPT_INACTIVE) ( 310 _In_ PIO_REPORT_INTERRUPT_ACTIVE_STATE_PARAMETERS Parameters 311 ); 312 313 typedef 314 VOID 315 (STDCALL *PFN_VF_CHECK_NX_POOL_TYPE) ( 316 _In_ POOL_TYPE PoolType, 317 _In_ PVOID CallingAddress, 318 _In_ ULONG PoolTag 319 ); 320 321 VOID 322 FxRegisterBugCheckCallback( 323 __inout PFX_DRIVER_GLOBALS FxDriverGlobals, 324 __in PDRIVER_OBJECT DriverObject 325 ); 326 327 VOID 328 FxUnregisterBugCheckCallback( 329 __inout PFX_DRIVER_GLOBALS FxDriverGlobals 330 ); 331 332 VOID 333 FxInitializeBugCheckDriverInfo(); 334 335 VOID 336 FxUninitializeBugCheckDriverInfo(); 337 338 VOID 339 FxCacheBugCheckDriverInfo( 340 __in PFX_DRIVER_GLOBALS FxDriverGlobals 341 ); 342 343 VOID 344 FxPurgeBugCheckDriverInfo( 345 __in PFX_DRIVER_GLOBALS FxDriverGlobals 346 ); 347 348 typedef struct _FX_DRIVER_TRACKER_CACHE_AWARE { 349 // 350 // Internal data types. 351 // 352 private: 353 typedef struct _FX_DRIVER_TRACKER_ENTRY { 354 volatile PFX_DRIVER_GLOBALS FxDriverGlobals; 355 } FX_DRIVER_TRACKER_ENTRY, *PFX_DRIVER_TRACKER_ENTRY; 356 357 // 358 // Public interface. 359 // 360 public: 361 _Must_inspect_result_ 362 NTSTATUS 363 Initialize(); 364 365 VOID 366 Uninitialize(); 367 368 _Must_inspect_result_ 369 NTSTATUS 370 Register( 371 __in PFX_DRIVER_GLOBALS FxDriverGlobals 372 ); 373 374 VOID 375 Deregister( 376 __in PFX_DRIVER_GLOBALS FxDriverGlobals 377 ); 378 379 // 380 // Tracks the driver usage on the current processor. 381 // KeGetCurrentProcessorNumberEx is called directly because the procgrp.lib 382 // provides the downlevel support for Vista, XP and Win2000. 383 // 384 __inline 385 VOID 386 TrackDriver( 387 __in PFX_DRIVER_GLOBALS FxDriverGlobals 388 ) 389 { 390 ASSERT(m_PoolToFree != NULL); 391 392 GetProcessorDriverEntryRef( 393 KeGetCurrentProcessorIndex())->FxDriverGlobals = 394 FxDriverGlobals; 395 } 396 397 // 398 // Returns the tracked driver (globals) on the current processor. 399 // KeGetCurrentProcessorNumberEx is called directly because the procgrp.lib 400 // provides the downlevel support for Vista, XP and Win2000. 401 // 402 _Must_inspect_result_ 403 __inline 404 PFX_DRIVER_GLOBALS 405 GetCurrentTrackedDriver() 406 { 407 PFX_DRIVER_GLOBALS fxDriverGlobals = NULL; 408 409 ASSERT(m_PoolToFree != NULL); 410 411 fxDriverGlobals = GetProcessorDriverEntryRef( 412 KeGetCurrentProcessorIndex())->FxDriverGlobals; 413 414 return fxDriverGlobals; 415 } 416 417 // 418 // Helper functions. 419 // 420 private: 421 // 422 // Returns the per-processor cache-aligned driver usage ref structure for 423 // given processor. 424 // 425 __inline 426 PFX_DRIVER_TRACKER_ENTRY 427 GetProcessorDriverEntryRef( 428 __in ULONG Index 429 ) 430 { 431 return ((PFX_DRIVER_TRACKER_ENTRY) (((PUCHAR)m_DriverUsage) + 432 Index * m_EntrySize)); 433 } 434 435 // 436 // Data members. 437 // 438 private: 439 // 440 // Pointer to array of cache-line aligned tracking driver structures. 441 // 442 PFX_DRIVER_TRACKER_ENTRY m_DriverUsage; 443 444 // 445 // Points to pool of per-proc tracking entries that needs to be freed. 446 // 447 PVOID m_PoolToFree; 448 449 // 450 // Size of each padded tracking driver structure. 451 // 452 ULONG m_EntrySize; 453 454 // 455 // Indicates # of entries in the array of tracking driver structures. 456 // 457 ULONG m_Number; 458 } FX_DRIVER_TRACKER_CACHE_AWARE, *PFX_DRIVER_TRACKER_CACHE_AWARE; 459 460 461 #include "fxglobals.h" 462 463 464 // 465 // This inline function tracks driver usage; This info is used by the 466 // debug dump callback routine for selecting which driver's log to save 467 // in the minidump. At this time we track the following OS to framework calls: 468 // (a) IRP dispatch (general, I/O, PnP, WMI). 469 // (b) Request's completion callbacks. 470 // (c) Work Item's (& System Work Item's) callback handlers. 471 // (d) Timer's callback handlers. 472 // 473 __inline 474 VOID 475 FX_TRACK_DRIVER( 476 __in PFX_DRIVER_GLOBALS FxDriverGlobals 477 ) 478 { 479 if (FxDriverGlobals->FxTrackDriverForMiniDumpLog) { 480 FxLibraryGlobals.DriverTracker.TrackDriver(FxDriverGlobals); 481 } 482 } 483 484 _Must_inspect_result_ 485 __inline 486 PVOID 487 FxAllocateFromNPagedLookasideListNoTracking ( 488 __in PNPAGED_LOOKASIDE_LIST Lookaside 489 ) 490 491 /*++ 492 493 Routine Description: 494 495 This function removes (pops) the first entry from the specified 496 nonpaged lookaside list. This function was added to allow request allocated 497 by a lookaside list to be freed by ExFreePool and hence do no tracking of statistics. 498 499 Arguments: 500 501 Lookaside - Supplies a pointer to a nonpaged lookaside list structure. 502 503 Return Value: 504 505 If an entry is removed from the specified lookaside list, then the 506 address of the entry is returned as the function value. Otherwise, 507 NULL is returned. 508 509 --*/ 510 511 { 512 513 PVOID Entry; 514 515 Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead); 516 517 if (Entry == NULL) { 518 Entry = (Lookaside->L.Allocate)(Lookaside->L.Type, 519 Lookaside->L.Size, 520 Lookaside->L.Tag); 521 } 522 523 return Entry; 524 } 525 526 __inline 527 VOID 528 FxFreeToNPagedLookasideListNoTracking ( 529 __in PNPAGED_LOOKASIDE_LIST Lookaside, 530 __in PVOID Entry 531 ) 532 /*++ 533 534 Routine Description: 535 536 This function inserts (pushes) the specified entry into the specified 537 nonpaged lookaside list. This function was added to allow request allocated 538 by a lookaside list to be freed by ExFreePool and hence do no tracking of statistics. 539 540 Arguments: 541 542 Lookaside - Supplies a pointer to a nonpaged lookaside list structure. 543 544 Entry - Supples a pointer to the entry that is inserted in the 545 lookaside list. 546 547 Return Value: 548 549 None. 550 551 --*/ 552 553 { 554 if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) { 555 (Lookaside->L.Free)(Entry); 556 } 557 else { 558 InterlockedPushEntrySList(&Lookaside->L.ListHead, 559 (PSLIST_ENTRY)Entry); 560 } 561 } 562 563 __inline 564 PVOID 565 FxAllocateFromNPagedLookasideList ( 566 _In_ PNPAGED_LOOKASIDE_LIST Lookaside, 567 _In_opt_ size_t ElementSize = 0 568 ) 569 570 /*++ 571 572 Routine Description: 573 574 This function removes (pops) the first entry from the specified 575 nonpaged lookaside list. 576 577 Arguments: 578 579 Lookaside - Supplies a pointer to a nonpaged lookaside list structure. 580 581 Return Value: 582 583 If an entry is removed from the specified lookaside list, then the 584 address of the entry is returned as the function value. Otherwise, 585 NULL is returned. 586 587 --*/ 588 589 { 590 591 PVOID Entry; 592 593 UNREFERENCED_PARAMETER(ElementSize); 594 595 Lookaside->L.TotalAllocates += 1; 596 597 Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead); 598 599 if (Entry == NULL) { 600 Lookaside->L.AllocateMisses += 1; 601 Entry = (Lookaside->L.Allocate)(Lookaside->L.Type, 602 Lookaside->L.Size, 603 Lookaside->L.Tag); 604 } 605 606 return Entry; 607 } 608 609 __inline 610 VOID 611 FxFreeToNPagedLookasideList ( 612 __in PNPAGED_LOOKASIDE_LIST Lookaside, 613 __in PVOID Entry 614 ) 615 /*++ 616 617 Routine Description: 618 619 This function inserts (pushes) the specified entry into the specified 620 nonpaged lookaside list. 621 622 Arguments: 623 624 Lookaside - Supplies a pointer to a nonpaged lookaside list structure. 625 626 Entry - Supples a pointer to the entry that is inserted in the 627 lookaside list. 628 629 Return Value: 630 631 None. 632 633 --*/ 634 635 { 636 Lookaside->L.TotalFrees += 1; 637 638 if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) { 639 Lookaside->L.FreeMisses += 1; 640 (Lookaside->L.Free)(Entry); 641 642 } 643 else { 644 InterlockedPushEntrySList(&Lookaside->L.ListHead, 645 (PSLIST_ENTRY)Entry); 646 } 647 } 648 649 _Must_inspect_result_ 650 __inline 651 PVOID 652 FxAllocateFromPagedLookasideList ( 653 __in PPAGED_LOOKASIDE_LIST Lookaside 654 ) 655 656 /*++ 657 658 Routine Description: 659 660 This function removes (pops) the first entry from the specified 661 paged lookaside list. 662 663 Arguments: 664 665 Lookaside - Supplies a pointer to a paged lookaside list structure. 666 667 Return Value: 668 669 If an entry is removed from the specified lookaside list, then the 670 address of the entry is returned as the function value. Otherwise, 671 NULL is returned. 672 673 --*/ 674 675 { 676 677 PVOID Entry; 678 679 Lookaside->L.TotalAllocates += 1; 680 681 Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead); 682 if (Entry == NULL) { 683 Lookaside->L.AllocateMisses += 1; 684 Entry = (Lookaside->L.Allocate)(Lookaside->L.Type, 685 Lookaside->L.Size, 686 Lookaside->L.Tag); 687 } 688 689 return Entry; 690 } 691 692 __inline 693 VOID 694 FxFreeToPagedLookasideList ( 695 __in PPAGED_LOOKASIDE_LIST Lookaside, 696 __in PVOID Entry 697 ) 698 /*++ 699 700 Routine Description: 701 702 This function inserts (pushes) the specified entry into the specified 703 paged lookaside list. 704 705 Arguments: 706 707 Lookaside - Supplies a pointer to a paged lookaside list structure. 708 709 Entry - Supples a pointer to the entry that is inserted in the 710 lookaside list. 711 712 Return Value: 713 714 None. 715 716 --*/ 717 718 { 719 Lookaside->L.TotalFrees += 1; 720 721 if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) { 722 Lookaside->L.FreeMisses += 1; 723 (Lookaside->L.Free)(Entry); 724 725 } else { 726 InterlockedPushEntrySList(&Lookaside->L.ListHead, 727 (PSLIST_ENTRY)Entry); 728 } 729 } 730 731 _Must_inspect_result_ 732 __inline 733 BOOLEAN 734 FxIsProcessorGroupSupported( 735 VOID 736 ) 737 { 738 // 739 // Groups are supported in Win 7 and forward. 740 // 741 return FxLibraryGlobals.ProcessorGroupSupport; 742 } 743 744 #ifdef __cplusplus 745 } 746 #endif 747