ReactOS 0.4.15-dev-8096-ga0eec98
fxbugcheckcallback.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) Microsoft Corporation. All rights reserved.
4
5Module Name:
6
7 FxBugcheckCallback.cpp
8
9Abstract:
10
11 This module contains the bugcheck callback functions for determining whether
12 a wdf driver caused a bugcheck and for capturing the IFR data to the mini-
13 dump file.
14
15Revision History:
16
17
18
19--*/
20
21
22#include "fxcorepch.hpp"
23#include "fxifr.h"
24#include "fxifrkm.h" // kernel mode only IFR definitions
25#include "fxldr.h"
26#include "fxbugcheck.h"
27
28#include <aux_klib.h>
29
30//
31// Disable warnings of features used by the standard headers
32//
33// Disable warning C4115: named type definition in parentheses
34// Disable warning C4200: nonstandard extension used : zero-sized array in struct/union
35// Disable warning C4201: nonstandard extension used : nameless struct/union
36// Disable warning C4214: nonstandard extension used : bit field types other than int
37//
38// #pragma warning(disable:4115 4200 4201 4214)
39#include <ntimage.h>
40// #pragma warning(default:4115 4200 4201 4214)
41
42
43extern "C" {
44
45//
46// Private methods.
47//
52 __in PFX_DRIVER_GLOBALS FxDriverGlobals
53 );
54
59 __out PVOID* ImageBase,
60 __out PULONG ImageSize
61 );
62
66 __inout PFX_DRIVER_GLOBALS FxDriverGlobals
67 );
68
69KBUGCHECK_REASON_CALLBACK_ROUTINE FxpBugCheckCallback;
70
71KBUGCHECK_REASON_CALLBACK_ROUTINE FxpLibraryBugCheckCallback;
72
77 __in PFX_DRIVER_GLOBALS FxDriverGlobals
78 )
79/*++
80
81Routine Description:
82
83 This routine will check the address to determine if it falls within the
84 image of a WDF component (Library, Client driver or Class Extension).
85 This is accomplished by traversing the WdfLdrGlobals.LoadedModuleList
86 and comparing each image start/end address with Address.
87
88Arguments:
89
90 PVOID Address - The address to be checked, and it need not be currently
91 paged in. In other words, it is NOT used in this routine as an
92 address, but more as a simple scaler into a 4GB (x86) array.
93
94 NOTE - Do not attempt to validatate Address, say via MmIsAddressValid(Address).
95 Address's memory could be paged out, but Address is still valid.
96
97 PFX_DRIVER_GLOBALS FxDriverGlobals - Driver's globals.
98
99Return Value:
100
101 TRUE indicates something was found, either library, client or both.
102 FALSE indicates either not found or invalid parameters.
103
104--*/
105{
106
107 if (NULL == Address || NULL == FxDriverGlobals) {
108 return FALSE;
109 }
110
111 if (Address >= FxDriverGlobals->ImageAddress &&
112 Address < WDF_PTR_ADD_OFFSET(FxDriverGlobals->ImageAddress,
113 FxDriverGlobals->ImageSize)) {
114 return TRUE;
115 }
116
117 return FALSE;
118}
119
124 __out PVOID* ImageBase,
125 __out PULONG ImageSize
126 )
127{
129 ULONG modulesSize = 0;
132 PVOID addressInImage = NULL;
133 ULONG numberOfModules;
134 ULONG i;
135
136 //
137 // Basic validation.
138 //
139 if (NULL == DriverObject || NULL == ImageBase || NULL == ImageSize) {
141 goto exit;
142 }
143
144 //
145 // Get the address of a well known entry in the Image.
146 //
147 addressInImage = (PVOID) DriverObject->DriverStart;
148 ASSERT(addressInImage != NULL);
149
150 //
151 // Initialize the AUX Kernel Library.
152 //
154 if (!NT_SUCCESS(status)) {
155 goto exit;
156 }
157
158 //
159 // Get size of area needed for loaded modules.
160 //
163 NULL);
164
165 if (!NT_SUCCESS(status) || (0 == modulesSize)) {
166 goto exit;
167 }
168
169 numberOfModules = modulesSize / sizeof(AUX_MODULE_EXTENDED_INFO);
170
171 //
172 // Allocate returned-sized memory for the modules area.
173 //
175 modulesSize,
176 '30LW');
177 if (NULL == modules) {
179 goto exit;
180 }
181
182 //
183 // Request the modules array be filled with module information.
184 //
187 modules);
188
189 if (!NT_SUCCESS(status)) {
190 goto exit;
191 }
192
193 //
194 // Traverse list, searching for the well known address in Image for which the
195 // module's Image Base Address is in its range.
196 //
197 module = modules;
198
199 for (i=0; i < numberOfModules; i++) {
200
201 if (addressInImage >= module->BasicInfo.ImageBase &&
202 addressInImage < WDF_PTR_ADD_OFFSET(module->BasicInfo.ImageBase,
203 module->ImageSize)) {
204
205 *ImageBase = module->BasicInfo.ImageBase;
206 *ImageSize = module->ImageSize;
207
209 goto exit;
210 }
211 module++;
212 }
213
215
216exit:
217
218 if (modules != NULL) {
219 ExFreePool(modules);
220 modules = NULL;
221 }
222
223 return status;
224}
225
229 __inout PFX_DRIVER_GLOBALS FxDriverGlobals
230 )
231/*++
232
233Routine Description:
234
235 This routine evaluates whether the driver's IFR data has to be written to
236 the mini-dump file.
237
238Arguments:
239
240 FxDriverGlobals - The driver globals of the wdf driver.
241
242Return Value:
243
244 TRUE - Indicates this driver's IFR log is to be captured in dump.
245 FALSE - Indicates this driver's log is (probably) not of interest.
246
247--*/
248{
249 PVOID codeAddr = NULL;
250 BOOLEAN found = FALSE;
251 KBUGCHECK_DATA bugCheckData = {0};
252
253 if (FxDriverGlobals->FxForceLogsInMiniDump) {
254 return TRUE;
255 }
256
257 //
258 // Retrieve the bugcheck parameters.
259 //
260 bugCheckData.BugCheckDataSize = sizeof(KBUGCHECK_DATA);
261 AuxKlibGetBugCheckData(&bugCheckData);
262
263 //
264 // Check whether the code address that caused the bugcheck is from this wdf
265 // driver.
266 //
267 switch (bugCheckData.BugCheckCode) {
268
269 case KERNEL_APC_PENDING_DURING_EXIT: // 0x20
270 codeAddr = (PVOID)bugCheckData.Parameter1;
271 found = FxpIsAddressKnownToWdf(codeAddr, FxDriverGlobals);
272 break;
273
274 case KMODE_EXCEPTION_NOT_HANDLED: // 0x1E
275 case SYSTEM_THREAD_EXCEPTION_NOT_HANDLED: // 0x7E
276 case KERNEL_MODE_EXCEPTION_NOT_HANDLED: // 0x8E
277 codeAddr = (PVOID)bugCheckData.Parameter2;
278 found = FxpIsAddressKnownToWdf(codeAddr, FxDriverGlobals);
279 break;
280
281 case PAGE_FAULT_IN_NONPAGED_AREA: // 0x50
282 codeAddr = (PVOID)bugCheckData.Parameter3;
283 found = FxpIsAddressKnownToWdf(codeAddr, FxDriverGlobals);
284 break;
285
286 case IRQL_NOT_LESS_OR_EQUAL: // 0xA
287 case DRIVER_IRQL_NOT_LESS_OR_EQUAL: // 0xD1
288 codeAddr = (PVOID)bugCheckData.Parameter4;
289 found = FxpIsAddressKnownToWdf(codeAddr, FxDriverGlobals);
290 break;
291 }
292
293 //
294 // If the code address was found in the wdf driver, then set the flag in the
295 // driver globals to indicate that the IFR data has to be written to the
296 // mini-dump.
297 //
298 if (found) {
299 FxDriverGlobals->FxForceLogsInMiniDump = TRUE;
300 }
301 return found;
302}
303
304VOID
310 __in ULONG ReasonSpecificLength
311 )
312
313/*++
314
315Routine Description:
316
317 BugCheck callback routine for WDF
318
319Arguments:
320
321 Reason - Must be KbCallbackSecondaryData
322 Record - Supplies the bugcheck record previously registered
323 ReasonSpecificData - Pointer to KBUGCHECK_SECONDARY_DUMP_DATA
324 ReasonSpecificLength - Sizeof(ReasonSpecificData)
325
326Return Value:
327
328 None
329
330Notes:
331 When a bugcheck happens the kernel bugcheck processor will make two passes
332 of all registered BugCheckCallbackRecord routines. The first pass, called
333 the "sizing pass" essentially queries all the callbacks to collect the
334 total size of the secondary dump data. In the second pass the actual data
335 is captured to the dump.
336
337--*/
338
339{
342 ULONG logSize;
343 BOOLEAN writeLog = FALSE;
344
346 UNREFERENCED_PARAMETER(ReasonSpecificLength);
347
348 ASSERT(ReasonSpecificLength >= sizeof(KBUGCHECK_SECONDARY_DUMP_DATA));
349 ASSERT(Reason == KbCallbackSecondaryDumpData);
350
352
353 //
354 // See if the IFR's minimum amount of data can fit in the dump
355 //
356 if (dumpData->MaximumAllowed < FxIFRMinLogSize) {
357 return;
358 }
359
360 //
361 // Get the driver globals containing the bugcheck callback record.
362 //
365 BugCheckCallbackRecord);
366
367 //
368 // If there is not IFR data, then this bugcheck callback does not have any
369 // data to write to the minidump.
370 //
372 return;
373 }
374
375 //
376 // Size is the length of the buffer which we log to. It should also include
377 // the size of the header (which was subtracted out in FxIFRStart).
378 //
379 logSize = ((PWDF_IFR_HEADER) fxDriverGlobals->WdfLogHeader)->Size +
380 sizeof(WDF_IFR_HEADER);
381
382 ASSERT(FxIFRMinLogSize <= logSize && logSize <= FxIFRMaxLogSize);
383
384 //
385 // Check whether log can fit in the dump.
386 //
387 if (logSize > dumpData->MaximumAllowed) {
388 return;
389 }
390
391 //
392 // Check whether this log is the one to copy.
393 //
395 //
396 // Let everyone know that we got the best match.
397 //
399
400 //
401 // Exact match driver.
402 //
403 writeLog = TRUE;
404 }
406 //
407 // So far we didn't get a perfect match. Make a best effort
408 // to find a good candidate for the driver dump log.
409 //
413 //
414 // Best effort match driver.
415 //
416 writeLog = TRUE;
417 }
418 }
419
420 if (writeLog) {
422 dumpData->OutBufferLength = logSize;
423 dumpData->Guid = WdfDumpGuid;
424 }
425}
426
427VOID
429 __inout PFX_DRIVER_GLOBALS FxDriverGlobals,
431 )
432{
433 UNICODE_STRING funcName;
436 BOOLEAN enableDriverTracking;
437
438 //
439 // If any problem during this setup, disable driver tracking.
440 //
441 enableDriverTracking = FxDriverGlobals->FxTrackDriverForMiniDumpLog;
442 FxDriverGlobals->FxTrackDriverForMiniDumpLog = FALSE;
443
444 //
445 // Zero out callback record.
446 //
447 callbackRecord = &FxDriverGlobals->BugCheckCallbackRecord;
448 RtlZeroMemory(callbackRecord, sizeof(KBUGCHECK_REASON_CALLBACK_RECORD));
449
450 //
451 // Get the Image base address and size before registering the bugcheck
452 // callbacks. If the image base address and size cannot be computed,
453 // then the bugcheck callbacks depend on these values being properly
454 // set.
455 //
456 FxDriverGlobals->ImageAddress = NULL;
457 FxDriverGlobals->ImageSize = 0;
458
460 &FxDriverGlobals->ImageAddress,
461 &FxDriverGlobals->ImageSize))) {
462 goto Done;
463 }
464
465
466
467
468
469
470
471
472
473
474 //
475 // The KeRegisterBugCheckReasonCallback exists for xp sp1 and above. So
476 // check whether this function is defined on the current OS and register
477 // for the bugcheck callback only if this function is defined.
478 //
479 RtlInitUnicodeString(&funcName, L"KeRegisterBugCheckReasonCallback");
481 MmGetSystemRoutineAddress(&funcName);
482
483 if (NULL == funcPtr) {
484 goto Done;
485 }
486
487 //
488 // Register this driver with driver tracker.
489 //
490 if (enableDriverTracking) {
492 FxDriverGlobals))) {
493 FxDriverGlobals->FxTrackDriverForMiniDumpLog = TRUE;
494 }
495 }
496
497 //
498 // Initialize the callback record.
499 //
500 KeInitializeCallbackRecord(callbackRecord);
501
502 //
503 // Register the bugcheck callback.
504 //
505 funcPtr(callbackRecord,
507 KbCallbackSecondaryDumpData,
508 (PUCHAR)FxDriverGlobals->Public.DriverName);
509
510 ASSERT(callbackRecord->CallbackRoutine != NULL);
511
512Done:;
513}
514
515VOID
517 __inout PFX_DRIVER_GLOBALS FxDriverGlobals
518 )
519{
520 UNICODE_STRING funcName;
523
524 callbackRecord = &FxDriverGlobals->BugCheckCallbackRecord;
525 if (NULL == callbackRecord->CallbackRoutine) {
526 goto Done;
527 }
528
529 //
530 // The KeDeregisterBugCheckReasonCallback exists for xp sp1 and above. So
531 // check whether this function is defined on the current OS and deregister
532 // from the bugcheck callback only if this function is defined.
533 //
534 RtlInitUnicodeString(&funcName, L"KeDeregisterBugCheckReasonCallback");
536 MmGetSystemRoutineAddress(&funcName);
537
538 if (NULL == funcPtr) {
539 goto Done;
540 }
541
542 funcPtr(callbackRecord);
543 callbackRecord->CallbackRoutine = NULL;
544
545 //
546 // Deregister this driver with driver tracker.
547 //
548 if (FxDriverGlobals->FxTrackDriverForMiniDumpLog) {
550 }
551
552Done:;
553}
554
555VOID
561 __in ULONG ReasonSpecificLength
562 )
563
564/*++
565
566Routine Description:
567
568 Global (framework-library) BugCheck callback routine for WDF
569
570Arguments:
571
572 Reason - Must be KbCallbackSecondaryData
573 Record - Supplies the bugcheck record previously registered
574 ReasonSpecificData - Pointer to KBUGCHECK_SECONDARY_DUMP_DATA
575 ReasonSpecificLength - Sizeof(ReasonSpecificData)
576
577Return Value:
578
579 None
580
581Notes:
582 When a bugcheck happens the kernel bugcheck processor will make two passes
583 of all registered BugCheckCallbackRecord routines. The first pass, called
584 the "sizing pass" essentially queries all the callbacks to collect the
585 total size of the secondary dump data. In the second pass the actual data
586 is captured to the dump.
587
588--*/
589
590{
592 ULONG dumpSize;
593
595 UNREFERENCED_PARAMETER(ReasonSpecificLength);
596
597 ASSERT(ReasonSpecificLength >= sizeof(KBUGCHECK_SECONDARY_DUMP_DATA));
598 ASSERT(Reason == KbCallbackSecondaryDumpData);
599
603 //
604 // See if the bugcheck driver info is more than can fit in the dump
605 //
606 if (dumpData->MaximumAllowed < dumpSize) {
608 dumpData->MaximumAllowed,
610 }
611
612 if (0 == dumpSize) {
613 goto Done;
614 }
615
616 //
617 // Ok, provide the info about the bugcheck data.
618 //
620 dumpData->OutBufferLength = dumpSize;
621 dumpData->Guid = WdfDumpGuid2;
622
623Done:;
624}
625
626VOID
628{
630 UNICODE_STRING funcName;
633 SIZE_T arraySize;
634 ULONG arrayCount;
635
636
638 RtlZeroMemory(callbackRecord, sizeof(KBUGCHECK_REASON_CALLBACK_RECORD));
639
643
644
645
646
647
648
649
650
651
652
653 //
654 // The KeRegisterBugCheckReasonCallback exists for xp sp1 and above. So
655 // check whether this function is defined on the current OS and register
656 // for the bugcheck callback only if this function is defined.
657 //
658 RtlInitUnicodeString(&funcName, L"KeRegisterBugCheckReasonCallback");
660 MmGetSystemRoutineAddress(&funcName);
661
662 if (NULL == funcPtr) {
663 goto Done;
664 }
665
668
672 arraySize,
673 FX_TAG);
674
676 goto Done;
677 }
678
680
681 //
682 // Init first entry for the framework.
683 //
685 FxLibraryGlobals.BugCheckDriverInfo[0].Version.Major = __WDF_MAJOR_VERSION;
686 FxLibraryGlobals.BugCheckDriverInfo[0].Version.Minor = __WDF_MINOR_VERSION;
687 FxLibraryGlobals.BugCheckDriverInfo[0].Version.Build = __WDF_BUILD_NUMBER;
688
692 WdfLdrType);
693
694 if (!NT_SUCCESS(status)) {
695 ASSERT(FALSE);
697 }
698
700
701 //
702 // Initialize the callback record.
703 //
704 KeInitializeCallbackRecord(callbackRecord);
705
706 //
707 // Register the bugcheck callback.
708 //
709 funcPtr(callbackRecord,
711 KbCallbackSecondaryDumpData,
713
714 ASSERT(callbackRecord->CallbackRoutine != NULL);
715
716Done:;
717}
718
719VOID
721{
722 UNICODE_STRING funcName;
725
726 //
727 // Deregister callback.
728 //
729
730
731
732
733
734
735
737 if (NULL == callbackRecord->CallbackRoutine) {
738 goto Done;
739 }
740
741 //
742 // The KeDeregisterBugCheckReasonCallback exists for xp sp1 and above. So
743 // check whether this function is defined on the current OS and deregister
744 // from the bugcheck callback only if this function is defined.
745 //
746 RtlInitUnicodeString(&funcName, L"KeDeregisterBugCheckReasonCallback");
748 MmGetSystemRoutineAddress(&funcName);
749
750 if (NULL == funcPtr) {
751 goto Done;
752 }
753
754 funcPtr(callbackRecord);
755 callbackRecord->CallbackRoutine = NULL;
756
757 //
758 // Release memory.
759 //
761 goto Done;
762 }
763
764 //
765 // Dynamic KMDF framework is unloading, make sure there is only one entry
766 // left in the driver info array; the framework lib was using this entry
767 // to store its version.
768 //
770
773
776
777Done:;
778}
779
780VOID
782 __in PFX_DRIVER_GLOBALS FxDriverGlobals
783 )
784{
785 KIRQL irql;
786 PFX_DUMP_DRIVER_INFO_ENTRY driverInfo = NULL;
787 PFX_DUMP_DRIVER_INFO_ENTRY oldDriverInfo = NULL;
788 ULONG newCount = 0;
789
790 //
791 // Clear driver index (0-based). Drivers do not use index 0.
792 //
793 FxDriverGlobals->BugCheckDriverInfoIndex = 0;
794
796 return;
797 }
798
800
801 //
802 // Make sure we have enough space, else allocate some more memory.
803 //
806
807 //
808 // Just exit if no more space in dump buffer.
809 //
812 ASSERT(FALSE);
813 goto Done;
814 }
815
818
819 //
820 // Allocate new buffer to hold driver info.
821 //
824 sizeof(FX_DUMP_DRIVER_INFO_ENTRY)* newCount,
825 FX_TAG);
826
827 if (NULL == driverInfo) {
828 goto Done;
829 }
830
831 //
832 // Copy data from old to new buffer.
833 //
834 RtlCopyMemory(driverInfo,
838 //
839 // Ok, replace global pointer and its count.
840 //
841 oldDriverInfo = FxLibraryGlobals.BugCheckDriverInfo;
844 driverInfo = NULL; // just in case.
845
846 //
847 // Free old memory.
848 //
849 MxMemory::MxFreePool(oldDriverInfo);
850 oldDriverInfo = NULL;
851 }
852
855 //
856 // Compute ptr to free entry.
857 //
860 //
861 // Cache some of this driver's info.
862 //
863 driverInfo->FxDriverGlobals = FxDriverGlobals;
864 driverInfo->Version = FxDriverGlobals->WdfBindInfo->Version;
865
866 C_ASSERT(sizeof(driverInfo->DriverName) ==
867 sizeof(FxDriverGlobals->Public.DriverName));
868 RtlCopyMemory(driverInfo->DriverName,
869 FxDriverGlobals->Public.DriverName,
870 sizeof(driverInfo->DriverName));
871 driverInfo->DriverName[ARRAY_SIZE(driverInfo->DriverName) - 1] = '\0';
872
873 //
874 // Cache this index for later when the driver is removed.
875 //
876 FxDriverGlobals->BugCheckDriverInfoIndex =
878
879 //
880 // Update global index.
881 //
883
884Done:
885
887}
888
889VOID
891 __in PFX_DRIVER_GLOBALS FxDriverGlobals
892 )
893{
894 KIRQL irql;
895 PFX_DUMP_DRIVER_INFO_ENTRY driverInfo = NULL;
896 ULONG driverIndex = 0;
897 ULONG shiftCount = 0;
898 ULONG i = 0;
899
901
902 //
903 // Zero means 'not used'.
904 //
905 driverIndex = FxDriverGlobals->BugCheckDriverInfoIndex;
906 if (0 == driverIndex) {
907 goto Done;
908 }
909
910 //
911 // Check if feature is not supported.
912 //
914 ASSERT(FALSE); // driverIndex > 0 with NULL array?
915 goto Done;
916 }
917
918
921
922 //
923 // Index boundary validation.
924 //
925 if (driverIndex >= FxLibraryGlobals.BugCheckDriverInfoIndex) {
926 ASSERT(FALSE);
927 goto Done;
928 }
929
930 //
931 // Compute ptr to driver info.
932 //
933 driverInfo = FxLibraryGlobals.BugCheckDriverInfo + driverIndex;
934
935 //
936 // Double-check that this is the same driver.
937 //
938 if (driverInfo->FxDriverGlobals != FxDriverGlobals) {
939 ASSERT(FALSE);
940 goto Done;
941 }
942
943 //
944 // Shift memory to fill hole and update global free index.
945 //
946 shiftCount = FxLibraryGlobals.BugCheckDriverInfoIndex - driverIndex - 1;
947 if (shiftCount > 0) {
948 RtlMoveMemory(driverInfo,
949 driverInfo + 1,
950 shiftCount * sizeof(FX_DUMP_DRIVER_INFO_ENTRY));
951 }
952
954
955 //
956 // Update cached index for all 'shifted' drivers.
957 //
958 for (i = driverIndex; i < FxLibraryGlobals.BugCheckDriverInfoIndex; ++i) {
960 BugCheckDriverInfoIndex--;
961 }
962
963Done:
964
966}
967
968//
969// Driver usage tracker functions
970//
973{
974 //
975 // Global initialization. It balances the global Uninitialize function.
976 // The real init is actually done by the Register function the first time
977 // a driver registers with the device tracker.
978 //
981 m_EntrySize = 0;
982 m_Number = 0;
983
984 return STATUS_SUCCESS;
985}
986
987VOID
989{
990 if (m_PoolToFree != NULL) {
991
992#ifdef DBG
993 for (ULONG index = 0; index < m_Number; ++index) {
994 PFX_DRIVER_TRACKER_ENTRY driverUsage = NULL;
995 driverUsage = GetProcessorDriverEntryRef(index);
996 ASSERT(NULL == driverUsage->FxDriverGlobals);
997 }
998#endif
1001 }
1002
1004 m_Number = 0;
1005}
1006
1009 __in PFX_DRIVER_GLOBALS /* FxDriverGlobals */
1010 )
1011{
1013 ULONG paddedSize = 0;
1014 ULONG index = 0;
1016 PFX_DRIVER_TRACKER_ENTRY driverUsage = NULL;
1017 UNICODE_STRING funcName;
1018 PVOID funcPtr = NULL;
1019
1020 //
1021 // Nothing to do if tracker is already initialized. No need for a lock
1022 // here since PnP already serializes driver initialization.
1023 //
1024 if (m_PoolToFree != NULL) {
1025 ASSERT(m_DriverUsage != NULL && m_Number != 0);
1027 goto Done;
1028 }
1029
1030 //
1031 // Intialize the procgrp down level library.
1032 //
1033 // WdmlibProcgrpInitialize(); __REACTOS__ : haha we don't support ProcGrp
1034
1035 //
1036 // Capture maximum number of processors.
1037 //
1038 RtlInitUnicodeString(&funcName, L"KeQueryMaximumProcessorCountEx");
1039 funcPtr = MmGetSystemRoutineAddress(&funcName);
1040 if (funcPtr != NULL) {
1041 //
1042 // Win 7 and forward.
1043 //
1046 }
1047 else {
1048 RtlInitUnicodeString(&funcName, L"KeQueryMaximumProcessorCount");
1049 funcPtr = MmGetSystemRoutineAddress(&funcName);
1050 if (funcPtr != NULL) {
1051 //
1052 // Windows Server 2008.
1053 //
1055 }
1056 else {
1061 //
1062 // XP (Major=5, Minor>0) and Vista (Major=6, Minor=0).
1063 //
1065 }
1066 else {
1067 //
1068 // This feature is not supported for Windows 2000.
1069 //
1070 ASSERT(FALSE);
1072 goto Done;
1073 }
1074 }
1075 }
1076
1077 //
1078 // Validate upper bound.
1079 //
1082 goto Done;
1083 }
1084
1085 //
1086 // Determine padded size of each tracking entry structure.
1087 //
1088 if (m_Number > 1 ) {
1089 RtlInitUnicodeString(&funcName, L"KeGetRecommendedSharedDataAlignment");
1090 funcPtr = MmGetSystemRoutineAddress(&funcName);
1091
1092 if (funcPtr != NULL) {
1093 //
1094 //XP and forward
1095 //
1096 paddedSize = ((PFN_KE_GET_RECOMMENDED_SHARED_DATA_ALIGNMENT)funcPtr)();
1097 ASSERT ((paddedSize & (paddedSize - 1)) == 0);
1098 }
1099 else {
1100 //
1101 // This feature is not supported for Windows 2000.
1102 //
1104 goto Done;
1105 }
1106 }
1107 else {
1108 paddedSize = sizeof(FX_DRIVER_TRACKER_ENTRY);
1109 }
1110
1111 ASSERT(sizeof(FX_DRIVER_TRACKER_ENTRY) <= paddedSize);
1112
1113 //
1114 // Remember the size.
1115 //
1116 m_EntrySize = paddedSize;
1117
1120 paddedSize * m_Number,
1121 FX_TAG);
1122 if (NULL == pool) {
1124 goto Done;
1125 }
1126
1127 //
1128 // Check if pool is aligned if this is a multi-proc.
1129 //
1130 if ((m_Number > 1) && !EXP_IS_PTR_ALIGNED_ON_BOUNDARY(pool, paddedSize)) {
1131 //
1132 // We will allocate a padded size, free the old pool.
1133 //
1135
1136 //
1137 // Allocate enough padding so we can start the refs on an aligned boundary
1138 //
1141 paddedSize * m_Number + paddedSize,
1142 FX_TAG);
1143 if (NULL == pool) {
1145 goto Done;
1146 }
1147
1148 driverUsage = (PFX_DRIVER_TRACKER_ENTRY)
1150
1151 }
1152 else {
1153 //
1154 // Already aligned pool.
1155 //
1156 driverUsage = pool;
1157 }
1158
1159 //
1160 // Remember the pool block to free.
1161 //
1163 m_DriverUsage = driverUsage;
1164
1165 //
1166 // Init driver usage entries.
1167 //
1168 for (index = 0; index < m_Number; ++index) {
1169 driverUsage = GetProcessorDriverEntryRef(index);
1170 driverUsage->FxDriverGlobals = NULL;
1171 }
1172
1173 //
1174 // All done.
1175 //
1177
1178Done:
1179 return status;
1180}
1181
1182VOID
1184 __in PFX_DRIVER_GLOBALS FxDriverGlobals
1185 )
1186{
1187 ULONG index = 0;
1188 PFX_DRIVER_TRACKER_ENTRY driverUsage = NULL;
1189
1190 //
1191 // Cleanup any refs to this driver's globals.
1192 //
1193 if (m_PoolToFree != NULL) {
1194
1195 ASSERT(m_DriverUsage != NULL && m_Number != 0);
1196
1197 for (index = 0; index < m_Number; ++index) {
1198 driverUsage = GetProcessorDriverEntryRef(index);
1199 if (driverUsage->FxDriverGlobals == FxDriverGlobals) {
1200 driverUsage->FxDriverGlobals = NULL;
1201 }
1202 }
1203 }
1204}
1205
1206} // extern "C"
unsigned char BOOLEAN
NTSTATUS NTAPI AuxKlibQueryModuleInformation(_In_ PULONG InformationLength, _In_ ULONG SizePerModule, _Inout_ PAUX_MODULE_EXTENDED_INFO ModuleInfo)
Definition: aux_klib.c:53
NTSTATUS NTAPI AuxKlibInitialize(VOID)
Definition: aux_klib.c:26
struct _KBUGCHECK_DATA KBUGCHECK_DATA
struct _AUX_MODULE_EXTENDED_INFO AUX_MODULE_EXTENDED_INFO
NTSTATUS AuxKlibGetBugCheckData(_Inout_ PKBUGCHECK_DATA BugCheckData)
Definition: aux_klib.c:178
LONG NTSTATUS
Definition: precomp.h:26
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:33
static __inline VOID MxFreePool(__in PVOID Ptr)
Definition: mxmemorykm.h:41
static __inline PVOID MxAllocatePoolWithTag(__in POOL_TYPE PoolType, __in SIZE_T NumberOfBytes, __in ULONG Tag)
Definition: mxmemorykm.h:30
#define __in
Definition: dbghelp.h:35
#define __inout
Definition: dbghelp.h:50
#define __out
Definition: dbghelp.h:62
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
KIRQL irql
Definition: wave.h:1
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PagedPool
Definition: env_spec_w32.h:308
struct _FX_DUMP_DRIVER_INFO_ENTRY * PFX_DUMP_DRIVER_INFO_ENTRY
#define EXP_ALIGN_UP_PTR_ON_BOUNDARY(_length, _alignment)
Definition: fxbugcheck.h:30
#define EXP_ALIGN_DOWN_ON_BOUNDARY(_size, _alignment)
Definition: fxbugcheck.h:46
#define FX_DUMP_DRIVER_INFO_INCREMENT
Definition: fxbugcheck.h:67
#define FX_MAX_DUMP_DRIVER_INFO_COUNT
Definition: fxbugcheck.h:73
struct _FX_DUMP_DRIVER_INFO_ENTRY FX_DUMP_DRIVER_INFO_ENTRY
#define FX_DRIVER_TRACKER_MAX_CPUS
Definition: fxbugcheck.h:62
#define EXP_IS_PTR_ALIGNED_ON_BOUNDARY(_pointer, _alignment)
Definition: fxbugcheck.h:38
VOID FxUnregisterBugCheckCallback(__inout PFX_DRIVER_GLOBALS FxDriverGlobals)
VOID FxCacheBugCheckDriverInfo(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
_Must_inspect_result_ NTSTATUS FxpGetImageBase(__in PDRIVER_OBJECT DriverObject, __out PVOID *ImageBase, __out PULONG ImageSize)
KBUGCHECK_REASON_CALLBACK_ROUTINE FxpLibraryBugCheckCallback
KBUGCHECK_REASON_CALLBACK_ROUTINE FxpBugCheckCallback
VOID FxPurgeBugCheckDriverInfo(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
_Must_inspect_result_ BOOLEAN FxpBugCheckCallbackFilter(__inout PFX_DRIVER_GLOBALS FxDriverGlobals)
_Must_inspect_result_ BOOLEAN FxpIsAddressKnownToWdf(__in PVOID Address, __in PFX_DRIVER_GLOBALS FxDriverGlobals)
VOID FxUninitializeBugCheckDriverInfo()
VOID FxRegisterBugCheckCallback(__inout PFX_DRIVER_GLOBALS FxDriverGlobals, __in PDRIVER_OBJECT DriverObject)
VOID FxInitializeBugCheckDriverInfo()
PFX_DRIVER_GLOBALS fxDriverGlobals
BOOLEAN(STDCALL * PFN_KE_DEREGISTER_BUGCHECK_REASON_CALLBACK)(__in PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecords)
Definition: fxglobalskm.h:92
ULONG(STDCALL * PFN_KE_GET_RECOMMENDED_SHARED_DATA_ALIGNMENT)(VOID)
Definition: fxglobalskm.h:222
BOOLEAN(STDCALL * PFN_KE_REGISTER_BUGCHECK_REASON_CALLBACK)(__in PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord, __in PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine, __in KBUGCHECK_CALLBACK_REASON Reason, __in PUCHAR Component)
Definition: fxglobalskm.h:83
ULONG(STDCALL * PFN_KE_QUERY_MAXIMUM_PROCESSOR_COUNT_EX)(__in USHORT GroupNumber)
Definition: fxglobalskm.h:204
ULONG(STDCALL * PFN_KE_QUERY_MAXIMUM_PROCESSOR_COUNT)(VOID)
Definition: fxglobalskm.h:210
struct _WDF_IFR_HEADER * PWDF_IFR_HEADER
struct _WDF_IFR_HEADER WDF_IFR_HEADER
@ FxIFRMaxLogSize
Definition: fxifrkm.h:24
@ FxIFRMinLogSize
Definition: fxifrkm.h:23
#define FX_TAG
Definition: fxmacros.hpp:155
GLuint index
Definition: glext.h:6031
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define C_ASSERT(e)
Definition: intsafe.h:73
PCHAR WdfLdrType
Definition: version.cpp:108
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
#define ASSERT(a)
Definition: mode.c:44
PVOID PVOID PWCHAR PVOID USHORT PULONG Reason
Definition: env.c:47
#define _Must_inspect_result_
Definition: ms_sal.h:558
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define ALL_PROCESSOR_GROUPS
Definition: ntbasedef.h:644
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
#define L(x)
Definition: ntvdm.h:50
static WCHAR Address[46]
Definition: ping.c:68
FxLibraryGlobalsType FxLibraryGlobals
Definition: globals.cpp:95
#define exit(n)
Definition: config.h:202
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
FX_DRIVER_TRACKER_CACHE_AWARE DriverTracker
Definition: fxglobals.h:812
PFX_DUMP_DRIVER_INFO_ENTRY BugCheckDriverInfo
Definition: fxglobals.h:791
RTL_OSVERSIONINFOEXW OsVersionInfo
Definition: fxglobals.h:770
KBUGCHECK_REASON_CALLBACK_RECORD BugCheckCallbackRecord
Definition: fxglobals.h:796
ULONG BugCheckDriverInfoCount
Definition: fxglobals.h:785
PFX_DRIVER_GLOBALS BestDriverForDumpLog
Definition: fxglobals.h:817
ULONG BugCheckDriverInfoIndex
Definition: fxglobals.h:780
MxLockNoDynam FxDriverGlobalsListLock
Definition: fxglobals.h:772
BOOLEAN FxTrackDriverForMiniDumpLog
Definition: fxglobals.h:483
Definition: fxglobalskm.h:353
volatile PFX_DRIVER_GLOBALS FxDriverGlobals
Definition: fxglobalskm.h:354
_Must_inspect_result_ NTSTATUS Initialize()
PFX_DRIVER_TRACKER_ENTRY m_DriverUsage
Definition: fxglobalskm.h:442
_Must_inspect_result_ __inline PFX_DRIVER_GLOBALS GetCurrentTrackedDriver()
Definition: fxglobalskm.h:405
_Must_inspect_result_ NTSTATUS Register(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
struct _FX_DRIVER_TRACKER_CACHE_AWARE::_FX_DRIVER_TRACKER_ENTRY * PFX_DRIVER_TRACKER_ENTRY
__inline PFX_DRIVER_TRACKER_ENTRY GetProcessorDriverEntryRef(__in ULONG Index)
Definition: fxglobalskm.h:427
struct _FX_DRIVER_TRACKER_CACHE_AWARE::_FX_DRIVER_TRACKER_ENTRY FX_DRIVER_TRACKER_ENTRY
VOID Deregister(__in PFX_DRIVER_GLOBALS FxDriverGlobals)
Definition: fxbugcheck.h:81
PFX_DRIVER_GLOBALS FxDriverGlobals
Definition: fxbugcheck.h:82
WDF_VERSION Version
Definition: fxbugcheck.h:83
CHAR DriverName[WDF_DRIVER_GLOBALS_NAME_LEN]
Definition: fxbugcheck.h:84
ULONG_PTR Parameter1
Definition: aux_klib.h:47
ULONG BugCheckDataSize
Definition: aux_klib.h:45
ULONG_PTR Parameter3
Definition: aux_klib.h:49
ULONG BugCheckCode
Definition: aux_klib.h:46
ULONG_PTR Parameter2
Definition: aux_klib.h:48
ULONG_PTR Parameter4
Definition: aux_klib.h:50
PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine
Definition: ketypes.h:311
ULONG dwMajorVersion
Definition: rtltypes.h:270
ULONG dwMinorVersion
Definition: rtltypes.h:271
WDF_MAJOR_VERSION Major
Definition: fxldr.h:122
WDF_BUILD_NUMBER Build
Definition: fxldr.h:124
WDF_MINOR_VERSION Minor
Definition: fxldr.h:123
Definition: ps.c:97
PVOID NTAPI MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName)
Definition: sysldr.c:3604
uint32_t * PULONG
Definition: typedefs.h:59
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
char CCHAR
Definition: typedefs.h:51
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STDCALL
Definition: wdf.h:45
#define WDF_PTR_ADD_OFFSET(_ptr, _offset)
Definition: wdfcore.h:144
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define KeInitializeCallbackRecord(CallbackRecord)
Definition: kefuncs.h:1387
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD _Inout_ PVOID ReasonSpecificData
Definition: ketypes.h:269
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record
Definition: ketypes.h:268
KBUGCHECK_CALLBACK_REASON
Definition: ketypes.h:259
struct _KBUGCHECK_SECONDARY_DUMP_DATA * PKBUGCHECK_SECONDARY_DUMP_DATA