ReactOS  0.4.15-dev-1150-g593bcce
debug.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * COPYRIGHT: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * FILE: ntoskrnl/io/debug.c
5  * PURPOSE: Useful functions for debugging IO and PNP managers
6  * PROGRAMMERS: Copyright 2020 Vadim Galyant <vgal@rambler.ru>
7  */
8 
9 #include <ntoskrnl.h>
10 #include "pnpio.h"
11 
12 #define NDEBUG
13 #include <debug.h>
14 
15 /* GLOBALS ********************************************************************/
16 
18 
19 /* FUNCTIONS ******************************************************************/
20 
21 /* CmResource */
22 
23 /* PipDumpCmResourceDescriptor() displays information about a Cm Descriptor
24 
25  DebugLevel: 0 - always dump
26  1 - dump if not defined NDEBUG
27 */
28 VOID
29 NTAPI
33 {
34  PAGED_CODE();
35 
36  if (DebugLevel != 0)
37  {
38 #ifdef NDEBUG
39  return;
40 #endif
41  }
42 
43  if (Descriptor == NULL)
44  {
45  DPRINT1("Dump CmDescriptor: Descriptor == NULL\n");
46  return;
47  }
48 
49  switch (Descriptor->Type)
50  {
51  case CmResourceTypePort:
52  DPRINT1("[%p:%X:%X] IO: Start %X:%X, Len %X\n", Descriptor, Descriptor->ShareDisposition, Descriptor->Flags, Descriptor->u.Port.Start.HighPart, Descriptor->u.Port.Start.LowPart, Descriptor->u.Port.Length);
53  break;
54 
56  DPRINT1("[%p:%X:%X] INT: Lev %X Vec %X Aff %IX\n", Descriptor, Descriptor->ShareDisposition, Descriptor->Flags, Descriptor->u.Interrupt.Level, Descriptor->u.Interrupt.Vector, Descriptor->u.Interrupt.Affinity);
57  break;
58 
60  DPRINT1("[%p:%X:%X] MEM: %X:%X Len %X\n", Descriptor, Descriptor->ShareDisposition, Descriptor->Flags, Descriptor->u.Memory.Start.HighPart, Descriptor->u.Memory.Start.LowPart, Descriptor->u.Memory.Length);
61  break;
62 
63  case CmResourceTypeDma:
64  DPRINT1("[%p:%X:%X] DMA: Channel %X Port %X\n", Descriptor, Descriptor->ShareDisposition, Descriptor->Flags, Descriptor->u.Dma.Channel, Descriptor->u.Dma.Port);
65  break;
66 
68  DPRINT1("[%p:%X:%X] DAT: DataSize %X\n", Descriptor, Descriptor->ShareDisposition, Descriptor->Flags, Descriptor->u.DeviceSpecificData.DataSize);
69  break;
70 
72  DPRINT1("[%p:%X:%X] BUS: Start %X Len %X Reserv %X\n", Descriptor, Descriptor->ShareDisposition, Descriptor->Flags, Descriptor->u.BusNumber.Start, Descriptor->u.BusNumber.Length, Descriptor->u.BusNumber.Reserved);
73  break;
74 
76  DPRINT1("[%p:%X:%X] PVT: D[0] %X D[1] %X D[2] %X\n", Descriptor, Descriptor->ShareDisposition, Descriptor->Flags, Descriptor->u.DevicePrivate.Data[0], Descriptor->u.DevicePrivate.Data[1], Descriptor->u.DevicePrivate.Data[2]);
77  break;
78 
79  default:
80  DPRINT1("[%p] Unknown type %X\n", Descriptor, Descriptor->Type);
81  break;
82  }
83 }
84 
85 /* PipGetNextCmPartialDescriptor() return poiner to next a Cm Descriptor */
86 
88 NTAPI
91 {
92  PCM_PARTIAL_RESOURCE_DESCRIPTOR NextDescriptor;
93 
94  /* Assume the descriptors are the fixed size ones */
95  NextDescriptor = CmDescriptor + 1;
96 
97  /* But check if this is actually a variable-sized descriptor */
98  if (CmDescriptor->Type == CmResourceTypeDeviceSpecific)
99  {
100  /* Add the size of the variable section as well */
101  NextDescriptor = (PVOID)((ULONG_PTR)NextDescriptor +
102  CmDescriptor->u.DeviceSpecificData.DataSize);
103  }
104 
105  /* Now the correct pointer has been computed, return it */
106  return NextDescriptor;
107 }
108 
109 /* PipDumpCmResourceList() displays information about a Cm List
110 
111  DebugLevel: 0 - always dump
112  1 - dump if not defined NDEBUG
113 */
114 VOID
115 NTAPI
117  _In_ PCM_RESOURCE_LIST CmResource,
119 {
122  ULONG ix;
123  ULONG jx;
124 
125  PAGED_CODE();
126 
127  if (DebugLevel != 0)
128  {
129 #ifdef NDEBUG
130  return;
131 #endif
132  }
133 
134  DPRINT1("Dump CmList: CmResource %p\n", CmResource);
135 
136  if (CmResource == NULL)
137  {
138  DPRINT1("PipDumpCmResourceList: CmResource == NULL\n");
139  return;
140  }
141 
142  if (CmResource->Count == 0)
143  {
144  DPRINT1("PipDumpCmResourceList: CmResource->Count == 0\n");
145  return;
146  }
147 
148  DPRINT1("FullList Count %x\n", CmResource->Count);
149 
150  FullList = &CmResource->List[0];
151 
152  for (ix = 0; ix < CmResource->Count; ix++)
153  {
154  DPRINT1("List #%X Iface %X Bus #%X Ver.%X Rev.%X Count %X\n",
155  ix,
156  FullList->InterfaceType,
157  FullList->BusNumber,
158  FullList->PartialResourceList.Version,
159  FullList->PartialResourceList.Revision,
160  FullList->PartialResourceList.Count);
161 
163 
164  for (jx = 0; jx < FullList->PartialResourceList.Count; jx++)
165  {
168  }
169 
171  }
172 }
173 
174 /* IoResource */
175 
176 /* PipDumpIoResourceDescriptor() displays information about a Io Descriptor
177 
178  DebugLevel: 0 - always dump
179  1 - dump if not defined NDEBUG
180 */
181 VOID
182 NTAPI
186 {
187  PAGED_CODE();
188 
189  if (DebugLevel != 0)
190  {
191 #ifdef NDEBUG
192  return;
193 #endif
194  }
195 
196  if (Descriptor == NULL)
197  {
198  DPRINT1("DumpResourceDescriptor: Descriptor == 0\n");
199  return;
200  }
201 
202  switch (Descriptor->Type)
203  {
204  case CmResourceTypeNull:
205  DPRINT1("[%p:%X:%X] O: Len %X Align %X Min %I64X, Max %I64X\n", Descriptor, Descriptor->Option, Descriptor->ShareDisposition, Descriptor->u.Generic.Length, Descriptor->u.Generic.Alignment, Descriptor->u.Generic.MinimumAddress.QuadPart, Descriptor->u.Generic.MaximumAddress.QuadPart);
206  break;
207 
208  case CmResourceTypePort:
209  DPRINT1("[%p:%X:%X] IO: Min %X:%X, Max %X:%X, Align %X Len %X\n", Descriptor, Descriptor->Option, Descriptor->ShareDisposition, Descriptor->u.Port.MinimumAddress.HighPart, Descriptor->u.Port.MinimumAddress.LowPart, Descriptor->u.Port.MaximumAddress.HighPart, Descriptor->u.Port.MaximumAddress.LowPart, Descriptor->u.Port.Alignment, Descriptor->u.Port.Length);
210  break;
211 
213  DPRINT1("[%p:%X:%X] INT: Min %X Max %X\n", Descriptor, Descriptor->Option, Descriptor->ShareDisposition, Descriptor->u.Interrupt.MinimumVector, Descriptor->u.Interrupt.MaximumVector);
214  break;
215 
217  DPRINT1("[%p:%X:%X] MEM: Min %X:%X, Max %X:%X, Align %X Len %X\n", Descriptor, Descriptor->Option, Descriptor->ShareDisposition, Descriptor->u.Memory.MinimumAddress.HighPart, Descriptor->u.Memory.MinimumAddress.LowPart, Descriptor->u.Memory.MaximumAddress.HighPart, Descriptor->u.Memory.MaximumAddress.LowPart, Descriptor->u.Memory.Alignment, Descriptor->u.Memory.Length);
218  break;
219 
220  case CmResourceTypeDma:
221  DPRINT1("[%p:%X:%X] DMA: Min %X Max %X\n", Descriptor, Descriptor->Option, Descriptor->ShareDisposition, Descriptor->u.Dma.MinimumChannel, Descriptor->u.Dma.MaximumChannel);
222  break;
223 
225  DPRINT1("[%p:%X:%X] BUS: Min %X Max %X Len %X\n", Descriptor, Descriptor->Option, Descriptor->ShareDisposition, Descriptor->u.BusNumber.MinBusNumber, Descriptor->u.BusNumber.MaxBusNumber, Descriptor->u.BusNumber.Length);
226  break;
227 
229  DPRINT1("[%p:%X:%X] CFG: Priority %X\n", Descriptor, Descriptor->Option, Descriptor->ShareDisposition, Descriptor->u.ConfigData.Priority);
230  break;
231 
233  DPRINT1("[%p:%X:%X] DAT: %X %X %X\n", Descriptor, Descriptor->Option, Descriptor->ShareDisposition, Descriptor->u.DevicePrivate.Data[0], Descriptor->u.DevicePrivate.Data[1], Descriptor->u.DevicePrivate.Data[2]);
234  break;
235 
236  default:
237  DPRINT1("[%p:%X:%X]. Unknown type %X\n", Descriptor, Descriptor->Option, Descriptor->ShareDisposition, Descriptor->Type);
238  break;
239  }
240 }
241 
242 /* PipDumpResourceRequirementsList() displays information about a Io List
243 
244  DebugLevel: 0 - always dump
245  1 - dump if not defined NDEBUG
246 */
247 VOID
248 NTAPI
252 {
253  PIO_RESOURCE_LIST AltList;
255  ULONG ix;
256  ULONG jx;
257 
258  PAGED_CODE();
259 
260  if (DebugLevel != 0)
261  {
262 #ifdef NDEBUG
263  return;
264 #endif
265  }
266 
267  if (IoResource == NULL)
268  {
269  DPRINT1("PipDumpResourceRequirementsList: IoResource == 0\n");
270  return;
271  }
272 
273  DPRINT1("Dump RequirementsList: IoResource %p\n", IoResource);
274  DPRINT1("Interface %X Bus %X Slot %X AlternativeLists %X\n",
275  IoResource->InterfaceType,
276  IoResource->BusNumber,
277  IoResource->SlotNumber,
278  IoResource->AlternativeLists);
279 
280  AltList = &IoResource->List[0];
281 
282  if (IoResource->AlternativeLists < 1)
283  {
284  DPRINT1("PipDumpResourceRequirementsList: AlternativeLists < 1\n");
285  return;
286  }
287 
288  for (ix = 0; ix < IoResource->AlternativeLists; ix++)
289  {
290  DPRINT1("AltList %p, AltList->Count %X\n", AltList, AltList->Count);
291 
292  for (jx = 0; jx < AltList->Count; jx++)
293  {
294  Descriptor = &AltList->Descriptors[jx];
296  }
297 
298  AltList = (PIO_RESOURCE_LIST)(AltList->Descriptors + AltList->Count);
299  DPRINT1("End Descriptors %p\n", AltList);
300  }
301 }
302 
303 /* Gets the name of the device node state. */
304 
305 PWSTR
306 NTAPI
309 {
310  switch (State)
311  {
313  return L"DeviceNodeUnspecified";
314 
316  return L"DeviceNodeUninitialized";
317 
319  return L"DeviceNodeInitialized";
320 
322  return L"DeviceNodeDriversAdded";
323 
325  return L"DeviceNodeResourcesAssigned";
326 
328  return L"DeviceNodeStartPending";
329 
331  return L"DeviceNodeStartCompletion";
332 
334  return L"DeviceNodeStartPostWork";
335 
336  case DeviceNodeStarted:
337  return L"DeviceNodeStarted";
338 
340  return L"DeviceNodeQueryStopped";
341 
342  case DeviceNodeStopped:
343  return L"DeviceNodeStopped";
344 
346  return L"DeviceNodeRestartCompletion";
347 
349  return L"DeviceNodeEnumeratePending";
350 
352  return L"DeviceNodeEnumerateCompletion";
353 
355  return L"DeviceNodeAwaitingQueuedDeletion";
356 
358  return L"DeviceNodeAwaitingQueuedRemoval";
359 
361  return L"DeviceNodeQueryRemoved";
362 
364  return L"DeviceNodeRemovePendingCloses";
365 
366  case DeviceNodeRemoved:
367  return L"DeviceNodeRemoved";
368 
370  return L"DeviceNodeDeletePendingCloses";
371 
372  case DeviceNodeDeleted:
373  return L"DeviceNodeDeleted";
374 
375  default:
376  break;
377  }
378 
379  if (State != MaxDeviceNodeState)
380  {
381  DPRINT1("PipGetDeviceNodeStateName: Unknown State %X\n", State);
382  }
383 
384  return L"";
385 }
386 
387 /* Dump list arbiters for the device node */
388 
389 VOID
390 NTAPI
393  _In_ ULONG NodeLevel)
394 {
395  DPRINT("Level %X DevNode %p for PDO %p\n", NodeLevel, DeviceNode, DeviceNode->PhysicalDeviceObject);
396 
397  /* Definitions needed for arbiter */
399 }
400 
401 /* PipDumpDeviceNode() displays information about a device node
402 
403  Flags is bitmask parametr:
404  1 - traversal of all children nodes
405  2 - dump allocated resources and boot configuration resources
406  4 - dump resources required
407  8 - dump translated resources
408 
409  DebugLevel: 0 - always dump
410  1 - dump if not defined NDEBUG
411 */
412 VOID
413 NTAPI
416  _In_ ULONG NodeLevel,
417  _In_ ULONG Flags,
419 {
420  PDEVICE_NODE ChildDeviceNode;
421 
422  if (DebugLevel != 0)
423  {
424 #ifdef NDEBUG
425  return;
426 #endif
427  }
428 
429  DPRINT1("* Level %X DevNode %p for PDO %p\n", NodeLevel, DeviceNode, DeviceNode->PhysicalDeviceObject);
430  DPRINT1("Instance %wZ\n", &DeviceNode->InstancePath);
431 if (DeviceNode->ServiceName.Length)
432  DPRINT1("Service %wZ\n", &DeviceNode->ServiceName);
433 #if 0
434  /* It is not used yet */
435  DPRINT1("State %X %S\n", DeviceNode->State, PipGetDeviceNodeStateName(DeviceNode->State));
436  DPRINT1("Prev State %X %S\n", DeviceNode->PreviousState, PipGetDeviceNodeStateName(DeviceNode->PreviousState));
437 #endif
438 if (DeviceNode->Problem)
439  DPRINT1("Problem %X\n", DeviceNode->Problem);
440 #if 0
441  /* It is not implemeted yet */
442  PipDumpArbiters(DeviceNode, NodeLevel);
443 #endif
444 
445  /* Allocated resources and Boot configuration (reported by IRP_MN_QUERY_RESOURCES)*/
447  {
448  if (DeviceNode->ResourceList)
449  {
450  DPRINT1("---------- ResourceList ----------\n");
452  }
453 
454  if (DeviceNode->BootResources)
455  {
456  DPRINT1("---------- BootResources ----------\n");
458  }
459  }
460 
461  /* Resources required (reported by IRP_MN_FILTER_RESOURCE_REQUIREMENTS) */
463  {
464  if (DeviceNode->ResourceRequirements)
465  {
466  DPRINT1("---------- ResourceRequirements ----------\n");
467  PipDumpResourceRequirementsList(DeviceNode->ResourceRequirements, DebugLevel);
468  }
469  }
470 
471  /* Translated resources (AllocatedResourcesTranslated) */
473  {
474  if (DeviceNode->ResourceListTranslated)
475  {
476  DPRINT1("---------- ResourceListTranslated ----------\n");
477  PipDumpCmResourceList(DeviceNode->ResourceListTranslated, DebugLevel);
478  }
479  }
480 
481  /* Traversal of all children nodes */
483  {
484  for (ChildDeviceNode = DeviceNode->Child;
485  ChildDeviceNode != NULL;
486  ChildDeviceNode = ChildDeviceNode->Sibling)
487  {
488  /* Recursive call */
489  PipDumpDeviceNode(ChildDeviceNode, (NodeLevel + 1), Flags, DebugLevel);
490  }
491  }
492 }
493 
494 /* PipDumpDeviceNodes() displays information about a node(s) in the device tree
495 
496  If DeviceNode is NULL, then the dump starts at the beginning of the device tree.
497 
498  Flags is bitmask parametr:
499  1 - traversal of all children nodes
500  2 - dump allocated resources and boot configuration resources
501  4 - dump resources required
502  8 - dump translated resources
503 
504  DebugLevel: 0 - always dump
505  1 - dump if not defined NDEBUG
506 
507  See also: Windows DDK -> General Driver Information ->
508  Kernel-Mode Driver Architecture -> Design Guide -> Plug and Play ->
509  Introduction to Plug and Play -> Hardware Resources
510 */
511 VOID
512 NTAPI
515  _In_ ULONG Flags,
517 {
518  if (DebugLevel != 0)
519  {
520 #ifdef NDEBUG
521  return;
522 #endif
523  }
524 
525  DPRINT1("PipDumpDeviceNodes: DeviceNode %X, Flags %X Level %X\n", DeviceNode, Flags, DebugLevel);
526 
527  if (DeviceNode == NULL)
528  {
530  }
531 
533 }
534 
535 /* EOF */
#define PIP_DUMP_FL_ALL_NODES
Definition: pnpio.h:5
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
struct _IO_RESOURCE_LIST * PIO_RESOURCE_LIST
#define CmResourceTypeDevicePrivate
Definition: hwresource.cpp:131
VOID NTAPI PipDumpCmResourceList(_In_ PCM_RESOURCE_LIST CmResource, _In_ ULONG DebugLevel)
Definition: debug.c:116
VOID NTAPI PipDumpDeviceNodes(_In_ PDEVICE_NODE DeviceNode, _In_ ULONG Flags, _In_ ULONG DebugLevel)
Definition: debug.c:513
uint16_t * PWSTR
Definition: typedefs.h:56
#define PIP_DUMP_FL_RES_ALLOCATED
Definition: pnpio.h:6
VOID NTAPI PipDumpIoResourceDescriptor(_In_ PIO_RESOURCE_DESCRIPTOR Descriptor, _In_ ULONG DebugLevel)
Definition: debug.c:183
ULONG DebugLevel
Definition: fbtusb.c:26
#define CmResourceTypePort
Definition: hwresource.cpp:123
uint32_t ULONG_PTR
Definition: typedefs.h:65
PDEVICE_NODE IopRootDeviceNode
Definition: devnode.c:18
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define PIP_DUMP_FL_RES_TRANSLATED
Definition: pnpio.h:8
struct _CM_FULL_RESOURCE_DESCRIPTOR * PCM_FULL_RESOURCE_DESCRIPTOR
enum _PNP_DEVNODE_STATE PNP_DEVNODE_STATE
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
void * PVOID
Definition: retypes.h:9
VOID NTAPI PipDumpDeviceNode(_In_ PDEVICE_NODE DeviceNode, _In_ ULONG NodeLevel, _In_ ULONG Flags, _In_ ULONG DebugLevel)
Definition: debug.c:414
VOID NTAPI PipDumpCmResourceDescriptor(_In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor, _In_ ULONG DebugLevel)
Definition: debug.c:30
VOID NTAPI PipDumpArbiters(_In_ PDEVICE_NODE DeviceNode, _In_ ULONG NodeLevel)
Definition: debug.c:391
IO_RESOURCE_DESCRIPTOR Descriptors[1]
#define CmResourceTypeConfigData
Definition: hwresource.cpp:130
#define CmResourceTypeNull
Definition: hwresource.cpp:122
_In_ PSTORAGE_PROPERTY_ID _Outptr_ PSTORAGE_DESCRIPTOR_HEADER * Descriptor
Definition: cdrom.h:932
PWSTR NTAPI PipGetDeviceNodeStateName(_In_ PNP_DEVNODE_STATE State)
Definition: debug.c:307
VOID NTAPI PipDumpResourceRequirementsList(_In_ PIO_RESOURCE_REQUIREMENTS_LIST IoResource, _In_ ULONG DebugLevel)
Definition: debug.c:249
Definition: Node.h:9
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
static const WCHAR L[]
Definition: oid.c:1250
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@384::@393 DeviceSpecificData
#define _In_
Definition: no_sal2.h:204
struct _DEVICE_NODE * Sibling
Definition: iotypes.h:823
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
PCM_PARTIAL_RESOURCE_DESCRIPTOR NTAPI PipGetNextCmPartialDescriptor(_In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor)
Definition: debug.c:89
#define PIP_DUMP_FL_RES_REQUIREMENTS
Definition: pnpio.h:7
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:115
#define CmResourceTypeBusNumber
Definition: hwresource.cpp:128
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@384 u
#define CmResourceTypeMemory
Definition: hwresource.cpp:125
#define CmResourceTypeDma
Definition: hwresource.cpp:126
#define PAGED_CODE()