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