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
TrackDriver_FX_DRIVER_TRACKER_CACHE_AWARE386     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
GetCurrentTrackedDriver_FX_DRIVER_TRACKER_CACHE_AWARE405     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
GetProcessorDriverEntryRef_FX_DRIVER_TRACKER_CACHE_AWARE427     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
FX_TRACK_DRIVER(__in PFX_DRIVER_GLOBALS FxDriverGlobals)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
FxAllocateFromNPagedLookasideListNoTracking(__in PNPAGED_LOOKASIDE_LIST Lookaside)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
FxFreeToNPagedLookasideListNoTracking(__in PNPAGED_LOOKASIDE_LIST Lookaside,__in PVOID Entry)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
FxFreeToNPagedLookasideList(__in PNPAGED_LOOKASIDE_LIST Lookaside,__in PVOID Entry)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
FxAllocateFromPagedLookasideList(__in PPAGED_LOOKASIDE_LIST Lookaside)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
FxFreeToPagedLookasideList(__in PPAGED_LOOKASIDE_LIST Lookaside,__in PVOID Entry)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
FxIsProcessorGroupSupported(VOID)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