ReactOS  0.4.14-dev-815-ge410a12
kdapi.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/kd64/kdapi.c
5  * PURPOSE: KD64 Public Routines and Internal Support
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  * Stefan Ginsberg (stefan.ginsberg@reactos.org)
8  */
9 
10 /* INCLUDES ******************************************************************/
11 
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15 
16 VOID NTAPI PspDumpThreads(BOOLEAN SystemThreads);
17 
18 /* PRIVATE FUNCTIONS *********************************************************/
19 
20 VOID
21 NTAPI
26 {
27  PCHAR DestinationBytes, SourceBytes;
28 
29  /* Copy the buffers 1 byte at a time */
30  DestinationBytes = Destination;
31  SourceBytes = Source;
32  while (Length--) *DestinationBytes++ = *SourceBytes++;
33 }
34 
35 VOID
36 NTAPI
40 {
41  PCHAR DestinationBytes;
42 
43  /* Zero the buffer 1 byte at a time */
44  DestinationBytes = Destination;
45  while (Length--) *DestinationBytes++ = 0;
46 }
47 
49 NTAPI
53  _In_ ULONG TotalSize,
56  _Out_opt_ PULONG ActualSize)
57 {
59  ULONG RemainingLength, CopyChunk;
60 
61  /* Check if we didn't get a chunk size or if it is too big */
62  if (ChunkSize == 0)
63  {
64  /* Default to 4 byte chunks */
65  ChunkSize = 4;
66  }
67  else if (ChunkSize > MMDBG_COPY_MAX_SIZE)
68  {
69  /* Normalize to maximum size */
71  }
72 
73  /* Copy the whole range in aligned chunks */
74  RemainingLength = TotalSize;
75  CopyChunk = 1;
76  while (RemainingLength > 0)
77  {
78  /*
79  * Determine the best chunk size for this round.
80  * The ideal size is aligned, isn't larger than the
81  * the remaining length and respects the chunk limit.
82  */
83  while (((CopyChunk * 2) <= RemainingLength) &&
84  (CopyChunk < ChunkSize) &&
85  ((Address & ((CopyChunk * 2) - 1)) == 0))
86  {
87  /* Increase it */
88  CopyChunk *= 2;
89  }
90 
91  /*
92  * The chunk size can be larger than the remaining size if this
93  * isn't the first round, so check if we need to shrink it back.
94  */
95  while (CopyChunk > RemainingLength)
96  {
97  /* Shrink it */
98  CopyChunk /= 2;
99  }
100 
101  /* Do the copy */
102  Status = MmDbgCopyMemory(Address, Buffer, CopyChunk, Flags);
103  if (!NT_SUCCESS(Status))
104  {
105  /* Copy failed, break out */
106  break;
107  }
108 
109  /* Update pointers and length for the next run */
110  Address = Address + CopyChunk;
111  Buffer = (PVOID)((ULONG_PTR)Buffer + CopyChunk);
112  RemainingLength = RemainingLength - CopyChunk;
113  }
114 
115  /* We may have modified executable code, flush the instruction cache */
116  KeSweepICache((PVOID)(ULONG_PTR)Address, TotalSize);
117 
118  /*
119  * Return the size we managed to copy and return
120  * success if we could copy the whole range.
121  */
122  if (ActualSize) *ActualSize = TotalSize - RemainingLength;
123  return RemainingLength == 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
124 }
125 
126 #ifdef _WINKD_
127 
128 VOID
129 NTAPI
130 KdpQueryMemory(IN PDBGKD_MANIPULATE_STATE64 State,
132 {
133  PDBGKD_QUERY_MEMORY Memory = &State->u.QueryMemory;
134  STRING Header;
136 
137  /* Validate the address space */
138  if (Memory->AddressSpace == DBGKD_QUERY_MEMORY_VIRTUAL)
139  {
140  /* Check if this is process memory */
141  if ((PVOID)(ULONG_PTR)Memory->Address < MmHighestUserAddress)
142  {
143  /* It is */
144  Memory->AddressSpace = DBGKD_QUERY_MEMORY_PROCESS;
145  }
146  else
147  {
148  /* Check if it's session space */
149  if (MmIsSessionAddress((PVOID)(ULONG_PTR)Memory->Address))
150  {
151  /* It is */
152  Memory->AddressSpace = DBGKD_QUERY_MEMORY_SESSION;
153  }
154  else
155  {
156  /* Not session space but some other kernel memory */
157  Memory->AddressSpace = DBGKD_QUERY_MEMORY_KERNEL;
158  }
159  }
160 
161  /* Set flags */
165  }
166  else
167  {
168  /* Invalid */
170  }
171 
172  /* Return structure */
173  State->ReturnStatus = Status;
174  Memory->Reserved = 0;
175 
176  /* Build header */
177  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
178  Header.Buffer = (PCHAR)State;
179 
180  /* Send the packet */
182  &Header,
183  NULL,
184  &KdpContext);
185 }
186 
187 VOID
188 NTAPI
189 KdpSearchMemory(IN PDBGKD_MANIPULATE_STATE64 State,
190  IN PSTRING Data,
192 {
193  //PDBGKD_SEARCH_MEMORY SearchMemory = &State->u.SearchMemory;
194  STRING Header;
195 
196  /* TODO */
197  KdpDprintf("Memory Search support is unimplemented!\n");
198 
199  /* Send a failure packet */
200  State->ReturnStatus = STATUS_UNSUCCESSFUL;
201  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
202  Header.Buffer = (PCHAR)State;
204  &Header,
205  NULL,
206  &KdpContext);
207 }
208 
209 VOID
210 NTAPI
211 KdpFillMemory(IN PDBGKD_MANIPULATE_STATE64 State,
212  IN PSTRING Data,
214 {
215  //PDBGKD_FILL_MEMORY FillMemory = &State->u.FillMemory;
216  STRING Header;
217 
218  /* TODO */
219  KdpDprintf("Memory Fill support is unimplemented!\n");
220 
221  /* Send a failure packet */
222  State->ReturnStatus = STATUS_UNSUCCESSFUL;
223  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
224  Header.Buffer = (PCHAR)State;
226  &Header,
227  NULL,
228  &KdpContext);
229 }
230 
231 VOID
232 NTAPI
233 KdpWriteBreakpoint(IN PDBGKD_MANIPULATE_STATE64 State,
234  IN PSTRING Data,
236 {
237  PDBGKD_WRITE_BREAKPOINT64 Breakpoint = &State->u.WriteBreakPoint;
238  STRING Header;
239 
240  /* Build header */
241  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
242  Header.Buffer = (PCHAR)State;
243  ASSERT(Data->Length == 0);
244 
245  /* Create the breakpoint */
246  Breakpoint->BreakPointHandle =
248  if (!Breakpoint->BreakPointHandle)
249  {
250  /* We failed */
251  State->ReturnStatus = STATUS_UNSUCCESSFUL;
252  }
253  else
254  {
255  /* Success! */
256  State->ReturnStatus = STATUS_SUCCESS;
257  }
258 
259  /* Send the packet */
261  &Header,
262  NULL,
263  &KdpContext);
264 }
265 
266 VOID
267 NTAPI
268 KdpRestoreBreakpoint(IN PDBGKD_MANIPULATE_STATE64 State,
269  IN PSTRING Data,
271 {
272  PDBGKD_RESTORE_BREAKPOINT RestoreBp = &State->u.RestoreBreakPoint;
273  STRING Header;
274 
275  /* Fill out the header */
276  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
277  Header.Buffer = (PCHAR)State;
278  ASSERT(Data->Length == 0);
279 
280  /* Get the version block */
281  if (KdpDeleteBreakpoint(RestoreBp->BreakPointHandle))
282  {
283  /* We're all good */
284  State->ReturnStatus = STATUS_SUCCESS;
285  }
286  else
287  {
288  /* We failed */
289  State->ReturnStatus = STATUS_UNSUCCESSFUL;
290  }
291 
292  /* Send the packet */
294  &Header,
295  NULL,
296  &KdpContext);
297 }
298 
299 NTSTATUS
300 NTAPI
301 KdpWriteBreakPointEx(IN PDBGKD_MANIPULATE_STATE64 State,
302  IN PSTRING Data,
304 {
305  //PDBGKD_BREAKPOINTEX = &State->u.BreakPointEx;
306  STRING Header;
307 
308  /* TODO */
309  KdpDprintf("Extended Breakpoint Write support is unimplemented!\n");
310 
311  /* Send a failure packet */
312  State->ReturnStatus = STATUS_UNSUCCESSFUL;
313  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
314  Header.Buffer = (PCHAR)State;
316  &Header,
317  Data,
318  &KdpContext);
319  return STATUS_UNSUCCESSFUL;
320 }
321 
322 VOID
323 NTAPI
324 KdpRestoreBreakPointEx(IN PDBGKD_MANIPULATE_STATE64 State,
325  IN PSTRING Data,
327 {
328  //PDBGKD_BREAKPOINTEX = &State->u.BreakPointEx;
329  STRING Header;
330 
331  /* TODO */
332  KdpDprintf("Extended Breakpoint Restore support is unimplemented!\n");
333 
334  /* Send a failure packet */
335  State->ReturnStatus = STATUS_UNSUCCESSFUL;
336  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
337  Header.Buffer = (PCHAR)State;
339  &Header,
340  Data,
341  &KdpContext);
342 }
343 
344 VOID
345 NTAPI
346 KdpWriteCustomBreakpoint(IN PDBGKD_MANIPULATE_STATE64 State,
347  IN PSTRING Data,
349 {
350  //PDBGKD_WRITE_CUSTOM_BREAKPOINT = &State->u.WriteCustomBreakpoint;
351  STRING Header;
352 
353  /* Not supported */
354  KdpDprintf("Custom Breakpoint Write is unimplemented\n");
355 
356  /* Send a failure packet */
357  State->ReturnStatus = STATUS_UNSUCCESSFUL;
358  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
359  Header.Buffer = (PCHAR)State;
361  &Header,
362  NULL,
363  &KdpContext);
364 }
365 
366 VOID
367 NTAPI
368 DumpTraceData(IN PSTRING TraceData)
369 {
370  /* Update the buffer */
372 
373  /* Setup the trace data */
374  TraceData->Length = (USHORT)(TraceDataBufferPosition * sizeof(ULONG));
375  TraceData->Buffer = (PCHAR)TraceDataBuffer;
376 
377  /* Reset the buffer location */
379 }
380 
381 VOID
382 NTAPI
383 KdpSetCommonState(IN ULONG NewState,
385  IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange)
386 {
387  ULONG InstructionCount;
388  BOOLEAN HadBreakpoints;
389 
390  /* Setup common stuff available for all CPU architectures */
391  WaitStateChange->NewState = NewState;
392  WaitStateChange->ProcessorLevel = KeProcessorLevel;
393  WaitStateChange->Processor = (USHORT)KeGetCurrentPrcb()->Number;
394  WaitStateChange->NumberProcessors = (ULONG)KeNumberProcessors;
395  WaitStateChange->Thread = (ULONG64)(LONG_PTR)KeGetCurrentThread();
396  WaitStateChange->ProgramCounter = (ULONG64)(LONG_PTR)KeGetContextPc(Context);
397 
398  /* Zero out the entire Control Report */
399  KdpZeroMemory(&WaitStateChange->AnyControlReport,
400  sizeof(DBGKD_ANY_CONTROL_REPORT));
401 
402  /* Now copy the instruction stream and set the count */
403  KdpCopyMemoryChunks((ULONG_PTR)WaitStateChange->ProgramCounter,
404  &WaitStateChange->ControlReport.InstructionStream[0],
406  0,
408  &InstructionCount);
409  WaitStateChange->ControlReport.InstructionCount = (USHORT)InstructionCount;
410 
411  /* Clear all the breakpoints in this region */
412  HadBreakpoints =
413  KdpDeleteBreakpointRange((PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter,
414  (PVOID)((ULONG_PTR)WaitStateChange->ProgramCounter +
415  WaitStateChange->ControlReport.InstructionCount - 1));
416  if (HadBreakpoints)
417  {
418  /* Copy the instruction stream again, this time without breakpoints */
419  KdpCopyMemoryChunks((ULONG_PTR)WaitStateChange->ProgramCounter,
420  &WaitStateChange->ControlReport.InstructionStream[0],
421  InstructionCount,
422  0,
424  NULL);
425  }
426 }
427 
428 VOID
429 NTAPI
431 {
432  /* Copy the version block */
435  sizeof(DBGKD_GET_VERSION64));
436 }
437 
438 VOID
439 NTAPI
440 KdpGetVersion(IN PDBGKD_MANIPULATE_STATE64 State)
441 {
442  STRING Header;
443 
444  /* Fill out the header */
445  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
446  Header.Buffer = (PCHAR)State;
447 
448  /* Get the version block */
449  KdpSysGetVersion(&State->u.GetVersion64);
450 
451  /* Fill out the state */
452  State->ApiNumber = DbgKdGetVersionApi;
453  State->ReturnStatus = STATUS_SUCCESS;
454 
455  /* Send the packet */
457  &Header,
458  NULL,
459  &KdpContext);
460 }
461 
462 VOID
463 NTAPI
464 KdpReadVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State,
465  IN PSTRING Data,
467 {
468  PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory;
469  STRING Header;
470  ULONG Length = ReadMemory->TransferCount;
471 
472  /* Setup the header */
473  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
474  Header.Buffer = (PCHAR)State;
475  ASSERT(Data->Length == 0);
476 
477  /* Validate length */
479  {
480  /* Overflow, set it to maximum possible */
482  }
483 
484  /* Do the read */
485  State->ReturnStatus = KdpCopyMemoryChunks(ReadMemory->TargetBaseAddress,
486  Data->Buffer,
487  Length,
488  0,
490  &Length);
491 
492  /* Return the actual length read */
493  ReadMemory->ActualBytesRead = Length;
494  Data->Length = (USHORT)Length;
495 
496  /* Send the packet */
498  &Header,
499  Data,
500  &KdpContext);
501 }
502 
503 VOID
504 NTAPI
505 KdpWriteVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State,
506  IN PSTRING Data,
508 {
509  PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory;
510  STRING Header;
511 
512  /* Setup the header */
513  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
514  Header.Buffer = (PCHAR)State;
515 
516  /* Do the write */
517  State->ReturnStatus = KdpCopyMemoryChunks(WriteMemory->TargetBaseAddress,
518  Data->Buffer,
519  Data->Length,
520  0,
523  &WriteMemory->ActualBytesWritten);
524 
525  /* Send the packet */
527  &Header,
528  NULL,
529  &KdpContext);
530 }
531 
532 VOID
533 NTAPI
534 KdpReadPhysicalMemory(IN PDBGKD_MANIPULATE_STATE64 State,
535  IN PSTRING Data,
537 {
538  PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory;
539  STRING Header;
540  ULONG Length = ReadMemory->TransferCount;
541  ULONG Flags, CacheFlags;
542 
543  /* Setup the header */
544  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
545  Header.Buffer = (PCHAR)State;
546  ASSERT(Data->Length == 0);
547 
548  /* Validate length */
550  {
551  /* Overflow, set it to maximum possible */
553  }
554 
555  /* Start with the default flags */
557 
558  /* Get the caching flags and check if a type is specified */
559  CacheFlags = ReadMemory->ActualBytesRead;
560  if (CacheFlags == DBGKD_CACHING_CACHED)
561  {
562  /* Cached */
564  }
565  else if (CacheFlags == DBGKD_CACHING_UNCACHED)
566  {
567  /* Uncached */
569  }
570  else if (CacheFlags == DBGKD_CACHING_WRITE_COMBINED)
571  {
572  /* Write Combined */
574  }
575 
576  /* Do the read */
577  State->ReturnStatus = KdpCopyMemoryChunks(ReadMemory->TargetBaseAddress,
578  Data->Buffer,
579  Length,
580  0,
581  Flags,
582  &Length);
583 
584  /* Return the actual length read */
585  ReadMemory->ActualBytesRead = Length;
586  Data->Length = (USHORT)Length;
587 
588  /* Send the packet */
590  &Header,
591  Data,
592  &KdpContext);
593 }
594 
595 VOID
596 NTAPI
597 KdpWritePhysicalMemory(IN PDBGKD_MANIPULATE_STATE64 State,
598  IN PSTRING Data,
600 {
601  PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory;
602  STRING Header;
603  ULONG Flags, CacheFlags;
604 
605  /* Setup the header */
606  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
607  Header.Buffer = (PCHAR)State;
608 
609  /* Start with the default flags */
611 
612  /* Get the caching flags and check if a type is specified */
613  CacheFlags = WriteMemory->ActualBytesWritten;
614  if (CacheFlags == DBGKD_CACHING_CACHED)
615  {
616  /* Cached */
618  }
619  else if (CacheFlags == DBGKD_CACHING_UNCACHED)
620  {
621  /* Uncached */
623  }
624  else if (CacheFlags == DBGKD_CACHING_WRITE_COMBINED)
625  {
626  /* Write Combined */
628  }
629 
630  /* Do the write */
631  State->ReturnStatus = KdpCopyMemoryChunks(WriteMemory->TargetBaseAddress,
632  Data->Buffer,
633  Data->Length,
634  0,
635  Flags,
636  &WriteMemory->ActualBytesWritten);
637 
638  /* Send the packet */
640  &Header,
641  NULL,
642  &KdpContext);
643 }
644 
645 VOID
646 NTAPI
647 KdpReadControlSpace(IN PDBGKD_MANIPULATE_STATE64 State,
648  IN PSTRING Data,
650 {
651  PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory;
652  STRING Header;
653  ULONG Length;
654 
655  /* Setup the header */
656  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
657  Header.Buffer = (PCHAR)State;
658  ASSERT(Data->Length == 0);
659 
660  /* Check the length requested */
661  Length = ReadMemory->TransferCount;
663  {
664  /* Use maximum allowed */
666  }
667 
668  /* Call the internal routine */
669  State->ReturnStatus = KdpSysReadControlSpace(State->Processor,
670  ReadMemory->TargetBaseAddress,
671  Data->Buffer,
672  Length,
673  &Length);
674 
675  /* Return the actual length read */
676  ReadMemory->ActualBytesRead = Length;
677  Data->Length = (USHORT)Length;
678 
679  /* Send the reply */
681  &Header,
682  Data,
683  &KdpContext);
684 }
685 
686 VOID
687 NTAPI
688 KdpWriteControlSpace(IN PDBGKD_MANIPULATE_STATE64 State,
689  IN PSTRING Data,
691 {
692  PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory;
693  STRING Header;
694 
695  /* Setup the header */
696  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
697  Header.Buffer = (PCHAR)State;
698 
699  /* Call the internal routine */
700  State->ReturnStatus = KdpSysWriteControlSpace(State->Processor,
701  WriteMemory->TargetBaseAddress,
702  Data->Buffer,
703  Data->Length,
704  &WriteMemory->ActualBytesWritten);
705 
706  /* Send the reply */
708  &Header,
709  Data,
710  &KdpContext);
711 }
712 
713 VOID
714 NTAPI
715 KdpGetContext(IN PDBGKD_MANIPULATE_STATE64 State,
716  IN PSTRING Data,
718 {
719  STRING Header;
721 
722  /* Setup the header */
723  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
724  Header.Buffer = (PCHAR)State;
725  ASSERT(Data->Length == 0);
726 
727  /* Make sure that this is a valid request */
728  if (State->Processor < KeNumberProcessors)
729  {
730  /* Check if the request is for this CPU */
731  if (State->Processor == KeGetCurrentPrcb()->Number)
732  {
733  /* We're just copying our own context */
735  }
736  else
737  {
738  /* Get the context from the PRCB array */
739  TargetContext = &KiProcessorBlock[State->Processor]->
740  ProcessorState.ContextFrame;
741  }
742 
743  /* Copy it over to the debugger */
744  KdpMoveMemory(Data->Buffer,
746  sizeof(CONTEXT));
747  Data->Length = sizeof(CONTEXT);
748 
749  /* Let the debugger set the context now */
751 
752  /* Finish up */
753  State->ReturnStatus = STATUS_SUCCESS;
754  }
755  else
756  {
757  /* Invalid request */
758  State->ReturnStatus = STATUS_UNSUCCESSFUL;
759  }
760 
761  /* Send the reply */
763  &Header,
764  Data,
765  &KdpContext);
766 }
767 
768 VOID
769 NTAPI
770 KdpSetContext(IN PDBGKD_MANIPULATE_STATE64 State,
771  IN PSTRING Data,
773 {
774  STRING Header;
776 
777  /* Setup the header */
778  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
779  Header.Buffer = (PCHAR)State;
780  ASSERT(Data->Length == sizeof(CONTEXT));
781 
782  /* Make sure that this is a valid request */
783  if ((State->Processor < KeNumberProcessors) &&
784  (KdpContextSent))
785  {
786  /* Check if the request is for this CPU */
787  if (State->Processor == KeGetCurrentPrcb()->Number)
788  {
789  /* We're just copying our own context */
791  }
792  else
793  {
794  /* Get the context from the PRCB array */
795  TargetContext = &KiProcessorBlock[State->Processor]->
796  ProcessorState.ContextFrame;
797  }
798 
799  /* Copy the new context to it */
801  Data->Buffer,
802  sizeof(CONTEXT));
803 
804  /* Finish up */
805  State->ReturnStatus = STATUS_SUCCESS;
806  }
807  else
808  {
809  /* Invalid request */
810  State->ReturnStatus = STATUS_UNSUCCESSFUL;
811  }
812 
813  /* Send the reply */
815  &Header,
816  NULL,
817  &KdpContext);
818 }
819 
820 VOID
821 NTAPI
822 KdpGetContextEx(IN PDBGKD_MANIPULATE_STATE64 State,
823  IN PSTRING Data,
825 {
826  STRING Header;
827  PDBGKD_CONTEXT_EX ContextEx;
829  ASSERT(Data->Length == 0);
830 
831  /* Get our struct */
832  ContextEx = &State->u.ContextEx;
833 
834  /* Set up the header */
835  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
836  Header.Buffer = (PCHAR)State;
837 
838  /* Make sure that this is a valid request */
839  if ((State->Processor < KeNumberProcessors) &&
840  (ContextEx->Offset + ContextEx->ByteCount) <= sizeof(CONTEXT))
841  {
842  /* Check if the request is for this CPU */
843  if (State->Processor == KeGetCurrentPrcb()->Number)
844  {
845  /* We're just copying our own context */
847  }
848  else
849  {
850  /* Get the context from the PRCB array */
851  TargetContext = &KiProcessorBlock[State->Processor]->
852  ProcessorState.ContextFrame;
853  }
854 
855  /* Copy what is requested */
856  KdpMoveMemory(Data->Buffer,
857  (PVOID)((ULONG_PTR)TargetContext + ContextEx->Offset),
858  ContextEx->ByteCount);
859 
860  /* KD copies all */
861  Data->Length = ContextEx->BytesCopied = ContextEx->ByteCount;
862 
863  /* Let the debugger set the context now */
865 
866  /* Finish up */
867  State->ReturnStatus = STATUS_SUCCESS;
868  }
869  else
870  {
871  /* Invalid request */
872  ContextEx->BytesCopied = 0;
873  State->ReturnStatus = STATUS_UNSUCCESSFUL;
874  }
875 
876  /* Send the reply */
878  &Header,
879  Data,
880  &KdpContext);
881 }
882 
883 VOID
884 NTAPI
885 KdpSetContextEx(IN PDBGKD_MANIPULATE_STATE64 State,
886  IN PSTRING Data,
888 {
889  STRING Header;
890  PDBGKD_CONTEXT_EX ContextEx;
892 
893  /* Get our struct */
894  ContextEx = &State->u.ContextEx;
895  ASSERT(Data->Length == ContextEx->ByteCount);
896 
897  /* Set up the header */
898  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
899  Header.Buffer = (PCHAR)State;
900 
901  /* Make sure that this is a valid request */
902  if ((State->Processor < KeNumberProcessors) &&
903  ((ContextEx->Offset + ContextEx->ByteCount) <= sizeof(CONTEXT)) &&
904  (KdpContextSent))
905  {
906  /* Check if the request is for this CPU */
907  if (State->Processor == KeGetCurrentPrcb()->Number)
908  {
909  /* We're just copying our own context */
911  }
912  else
913  {
914  /* Get the context from the PRCB array */
915  TargetContext = &KiProcessorBlock[State->Processor]->
916  ProcessorState.ContextFrame;
917  }
918 
919  /* Copy what is requested */
921  Data->Buffer,
922  ContextEx->ByteCount);
923 
924  /* KD copies all */
925  ContextEx->BytesCopied = ContextEx->ByteCount;
926 
927  /* Finish up */
928  State->ReturnStatus = STATUS_SUCCESS;
929  }
930  else
931  {
932  /* Invalid request */
933  ContextEx->BytesCopied = 0;
934  State->ReturnStatus = STATUS_UNSUCCESSFUL;
935  }
936 
937  /* Send the reply */
939  &Header,
940  NULL,
941  &KdpContext);
942 }
943 
944 VOID
945 NTAPI
946 KdpCauseBugCheck(IN PDBGKD_MANIPULATE_STATE64 State)
947 {
948  /* Crash with the special code */
949  KeBugCheck(MANUALLY_INITIATED_CRASH);
950 }
951 
952 VOID
953 NTAPI
954 KdpReadMachineSpecificRegister(IN PDBGKD_MANIPULATE_STATE64 State,
955  IN PSTRING Data,
957 {
958  STRING Header;
959  PDBGKD_READ_WRITE_MSR ReadMsr = &State->u.ReadWriteMsr;
960  LARGE_INTEGER MsrValue;
961 
962  /* Setup the header */
963  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
964  Header.Buffer = (PCHAR)State;
965  ASSERT(Data->Length == 0);
966 
967  /* Call the internal routine */
968  State->ReturnStatus = KdpSysReadMsr(ReadMsr->Msr,
969  &MsrValue);
970 
971  /* Return the data */
972  ReadMsr->DataValueLow = MsrValue.LowPart;
973  ReadMsr->DataValueHigh = MsrValue.HighPart;
974 
975  /* Send the reply */
977  &Header,
978  NULL,
979  &KdpContext);
980 }
981 
982 VOID
983 NTAPI
984 KdpWriteMachineSpecificRegister(IN PDBGKD_MANIPULATE_STATE64 State,
985  IN PSTRING Data,
987 {
988  STRING Header;
989  PDBGKD_READ_WRITE_MSR WriteMsr = &State->u.ReadWriteMsr;
990  LARGE_INTEGER MsrValue;
991 
992  /* Setup the header */
993  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
994  Header.Buffer = (PCHAR)State;
995  ASSERT(Data->Length == 0);
996 
997  /* Call the internal routine */
998  MsrValue.LowPart = WriteMsr->DataValueLow;
999  MsrValue.HighPart = WriteMsr->DataValueHigh;
1000  State->ReturnStatus = KdpSysWriteMsr(WriteMsr->Msr,
1001  &MsrValue);
1002 
1003  /* Send the reply */
1005  &Header,
1006  NULL,
1007  &KdpContext);
1008 }
1009 
1010 VOID
1011 NTAPI
1012 KdpGetBusData(IN PDBGKD_MANIPULATE_STATE64 State,
1013  IN PSTRING Data,
1015 {
1016  STRING Header;
1017  PDBGKD_GET_SET_BUS_DATA GetBusData = &State->u.GetSetBusData;
1018  ULONG Length;
1019 
1020  /* Setup the header */
1021  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
1022  Header.Buffer = (PCHAR)State;
1023  ASSERT(Data->Length == 0);
1024 
1025  /* Check the length requested */
1026  Length = GetBusData->Length;
1028  {
1029  /* Use maximum allowed */
1031  }
1032 
1033  /* Call the internal routine */
1034  State->ReturnStatus = KdpSysReadBusData(GetBusData->BusDataType,
1035  GetBusData->BusNumber,
1036  GetBusData->SlotNumber,
1037  GetBusData->Offset,
1038  Data->Buffer,
1039  Length,
1040  &Length);
1041 
1042  /* Return the actual length read */
1043  GetBusData->Length = Length;
1044  Data->Length = (USHORT)Length;
1045 
1046  /* Send the reply */
1048  &Header,
1049  Data,
1050  &KdpContext);
1051 }
1052 
1053 VOID
1054 NTAPI
1055 KdpSetBusData(IN PDBGKD_MANIPULATE_STATE64 State,
1056  IN PSTRING Data,
1058 {
1059  STRING Header;
1060  PDBGKD_GET_SET_BUS_DATA SetBusData = &State->u.GetSetBusData;
1061  ULONG Length;
1062 
1063  /* Setup the header */
1064  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
1065  Header.Buffer = (PCHAR)State;
1066 
1067  /* Call the internal routine */
1068  State->ReturnStatus = KdpSysWriteBusData(SetBusData->BusDataType,
1069  SetBusData->BusNumber,
1070  SetBusData->SlotNumber,
1071  SetBusData->Offset,
1072  Data->Buffer,
1073  SetBusData->Length,
1074  &Length);
1075 
1076  /* Return the actual length written */
1077  SetBusData->Length = Length;
1078 
1079  /* Send the reply */
1081  &Header,
1082  NULL,
1083  &KdpContext);
1084 }
1085 
1086 VOID
1087 NTAPI
1088 KdpReadIoSpace(IN PDBGKD_MANIPULATE_STATE64 State,
1089  IN PSTRING Data,
1091 {
1092  STRING Header;
1093  PDBGKD_READ_WRITE_IO64 ReadIo = &State->u.ReadWriteIo;
1094 
1095  /* Setup the header */
1096  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
1097  Header.Buffer = (PCHAR)State;
1098  ASSERT(Data->Length == 0);
1099 
1100  /*
1101  * Clear the value so 1 or 2 byte reads
1102  * don't leave the higher bits unmodified
1103  */
1104  ReadIo->DataValue = 0;
1105 
1106  /* Call the internal routine */
1107  State->ReturnStatus = KdpSysReadIoSpace(Isa,
1108  0,
1109  1,
1110  ReadIo->IoAddress,
1111  &ReadIo->DataValue,
1112  ReadIo->DataSize,
1113  &ReadIo->DataSize);
1114 
1115  /* Send the reply */
1117  &Header,
1118  NULL,
1119  &KdpContext);
1120 }
1121 
1122 VOID
1123 NTAPI
1124 KdpWriteIoSpace(IN PDBGKD_MANIPULATE_STATE64 State,
1125  IN PSTRING Data,
1127 {
1128  STRING Header;
1129  PDBGKD_READ_WRITE_IO64 WriteIo = &State->u.ReadWriteIo;
1130 
1131  /* Setup the header */
1132  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
1133  Header.Buffer = (PCHAR)State;
1134  ASSERT(Data->Length == 0);
1135 
1136  /* Call the internal routine */
1137  State->ReturnStatus = KdpSysWriteIoSpace(Isa,
1138  0,
1139  1,
1140  WriteIo->IoAddress,
1141  &WriteIo->DataValue,
1142  WriteIo->DataSize,
1143  &WriteIo->DataSize);
1144 
1145  /* Send the reply */
1147  &Header,
1148  NULL,
1149  &KdpContext);
1150 }
1151 
1152 VOID
1153 NTAPI
1154 KdpReadIoSpaceExtended(IN PDBGKD_MANIPULATE_STATE64 State,
1155  IN PSTRING Data,
1157 {
1158  STRING Header;
1159  PDBGKD_READ_WRITE_IO_EXTENDED64 ReadIoExtended = &State->u.
1160  ReadWriteIoExtended;
1161 
1162  /* Setup the header */
1163  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
1164  Header.Buffer = (PCHAR)State;
1165  ASSERT(Data->Length == 0);
1166 
1167  /*
1168  * Clear the value so 1 or 2 byte reads
1169  * don't leave the higher bits unmodified
1170  */
1171  ReadIoExtended->DataValue = 0;
1172 
1173  /* Call the internal routine */
1174  State->ReturnStatus = KdpSysReadIoSpace(ReadIoExtended->InterfaceType,
1175  ReadIoExtended->BusNumber,
1176  ReadIoExtended->AddressSpace,
1177  ReadIoExtended->IoAddress,
1178  &ReadIoExtended->DataValue,
1179  ReadIoExtended->DataSize,
1180  &ReadIoExtended->DataSize);
1181 
1182  /* Send the reply */
1184  &Header,
1185  NULL,
1186  &KdpContext);
1187 }
1188 
1189 VOID
1190 NTAPI
1191 KdpWriteIoSpaceExtended(IN PDBGKD_MANIPULATE_STATE64 State,
1192  IN PSTRING Data,
1194 {
1195  STRING Header;
1196  PDBGKD_READ_WRITE_IO_EXTENDED64 WriteIoExtended = &State->u.
1197  ReadWriteIoExtended;
1198 
1199  /* Setup the header */
1200  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
1201  Header.Buffer = (PCHAR)State;
1202  ASSERT(Data->Length == 0);
1203 
1204  /* Call the internal routine */
1205  State->ReturnStatus = KdpSysWriteIoSpace(WriteIoExtended->InterfaceType,
1206  WriteIoExtended->BusNumber,
1207  WriteIoExtended->AddressSpace,
1208  WriteIoExtended->IoAddress,
1209  &WriteIoExtended->DataValue,
1210  WriteIoExtended->DataSize,
1211  &WriteIoExtended->DataSize);
1212 
1213  /* Send the reply */
1215  &Header,
1216  NULL,
1217  &KdpContext);
1218 }
1219 
1220 VOID
1221 NTAPI
1222 KdpCheckLowMemory(IN PDBGKD_MANIPULATE_STATE64 State)
1223 {
1224  STRING Header;
1225 
1226  /* Setup the header */
1227  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
1228  Header.Buffer = (PCHAR)State;
1229 
1230  /* Call the internal routine */
1231  State->ReturnStatus = KdpSysCheckLowMemory(MMDBG_COPY_UNSAFE);
1232 
1233  /* Send the reply */
1235  &Header,
1236  NULL,
1237  &KdpContext);
1238 }
1239 
1240 VOID
1241 NTAPI
1242 KdpNotSupported(IN PDBGKD_MANIPULATE_STATE64 State)
1243 {
1244  STRING Header;
1245 
1246  /* Set failure */
1247  State->ReturnStatus = STATUS_UNSUCCESSFUL;
1248 
1249  /* Setup the packet */
1250  Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
1251  Header.Buffer = (PCHAR)State;
1252 
1253  /* Send it */
1255  &Header,
1256  NULL,
1257  &KdpContext);
1258 }
1259 
1261 NTAPI
1262 KdpSendWaitContinue(IN ULONG PacketType,
1263  IN PSTRING SendHeader,
1266 {
1267  STRING Data, Header;
1268  DBGKD_MANIPULATE_STATE64 ManipulateState;
1269  ULONG Length;
1270  KDSTATUS RecvCode;
1271 
1272  /* Setup the Manipulate State structure */
1273  Header.MaximumLength = sizeof(DBGKD_MANIPULATE_STATE64);
1274  Header.Buffer = (PCHAR)&ManipulateState;
1275  Data.MaximumLength = sizeof(KdpMessageBuffer);
1276  Data.Buffer = KdpMessageBuffer;
1277 
1278  /*
1279  * Reset the context state to ensure the debugger has received
1280  * the current context before it sets it.
1281  */
1283 
1284 SendPacket:
1285  /* Send the Packet */
1286  KdSendPacket(PacketType, SendHeader, SendData, &KdpContext);
1287 
1288  /* If the debugger isn't present anymore, just return success */
1290 
1291  /* Main processing Loop */
1292  for (;;)
1293  {
1294  /* Receive Loop */
1295  do
1296  {
1297  /* Wait to get a reply to our packet */
1299  &Header,
1300  &Data,
1301  &Length,
1302  &KdpContext);
1303 
1304  /* If we got a resend request, do it */
1305  if (RecvCode == KdPacketNeedsResend) goto SendPacket;
1306  } while (RecvCode == KdPacketTimedOut);
1307 
1308  /* Now check what API we got */
1309  switch (ManipulateState.ApiNumber)
1310  {
1312 
1313  /* Read virtual memory */
1314  KdpReadVirtualMemory(&ManipulateState, &Data, Context);
1315  break;
1316 
1318 
1319  /* Write virtual memory */
1320  KdpWriteVirtualMemory(&ManipulateState, &Data, Context);
1321  break;
1322 
1323  case DbgKdGetContextApi:
1324 
1325  /* Get the current context */
1326  KdpGetContext(&ManipulateState, &Data, Context);
1327  break;
1328 
1329  case DbgKdSetContextApi:
1330 
1331  /* Set a new context */
1332  KdpSetContext(&ManipulateState, &Data, Context);
1333  break;
1334 
1336 
1337  /* Write the breakpoint */
1338  KdpWriteBreakpoint(&ManipulateState, &Data, Context);
1339  break;
1340 
1342 
1343  /* Restore the breakpoint */
1344  KdpRestoreBreakpoint(&ManipulateState, &Data, Context);
1345  break;
1346 
1347  case DbgKdContinueApi:
1348 
1349  /* Simply continue */
1350  return NT_SUCCESS(ManipulateState.u.Continue.ContinueStatus);
1351 
1353 
1354  /* Read control space */
1355  KdpReadControlSpace(&ManipulateState, &Data, Context);
1356  break;
1357 
1359 
1360  /* Write control space */
1361  KdpWriteControlSpace(&ManipulateState, &Data, Context);
1362  break;
1363 
1364  case DbgKdReadIoSpaceApi:
1365 
1366  /* Read I/O Space */
1367  KdpReadIoSpace(&ManipulateState, &Data, Context);
1368  break;
1369 
1370  case DbgKdWriteIoSpaceApi:
1371 
1372  /* Write I/O Space */
1373  KdpWriteIoSpace(&ManipulateState, &Data, Context);
1374  break;
1375 
1376  case DbgKdRebootApi:
1377 
1378  /* Reboot the system */
1380  break;
1381 
1382  case DbgKdContinueApi2:
1383 
1384  /* Check if caller reports success */
1385  if (NT_SUCCESS(ManipulateState.u.Continue2.ContinueStatus))
1386  {
1387  /* Update the state */
1388  KdpGetStateChange(&ManipulateState, Context);
1389  return ContinueSuccess;
1390  }
1391  else
1392  {
1393  /* Return an error */
1394  return ContinueError;
1395  }
1396 
1398 
1399  /* Read physical memory */
1400  KdpReadPhysicalMemory(&ManipulateState, &Data, Context);
1401  break;
1402 
1404 
1405  /* Write physical memory */
1406  KdpWritePhysicalMemory(&ManipulateState, &Data, Context);
1407  break;
1408 
1412 
1413  /* TODO */
1414  KdpDprintf("Special Call support is unimplemented!\n");
1415  KdpNotSupported(&ManipulateState);
1416  break;
1417 
1420 
1421  /* TODO */
1422  KdpDprintf("Internal Breakpoint support is unimplemented!\n");
1423  KdpNotSupported(&ManipulateState);
1424  break;
1425 
1427 
1428  /* Read I/O Space */
1429  KdpReadIoSpaceExtended(&ManipulateState, &Data, Context);
1430  break;
1431 
1433 
1434  /* Write I/O Space */
1435  KdpWriteIoSpaceExtended(&ManipulateState, &Data, Context);
1436  break;
1437 
1438  case DbgKdGetVersionApi:
1439 
1440  /* Get version data */
1441  KdpGetVersion(&ManipulateState);
1442  break;
1443 
1445 
1446  /* Write the breakpoint and check if it failed */
1447  if (!NT_SUCCESS(KdpWriteBreakPointEx(&ManipulateState,
1448  &Data,
1449  Context)))
1450  {
1451  /* Return an error */
1452  return ContinueError;
1453  }
1454  break;
1455 
1457 
1458  /* Restore the breakpoint */
1459  KdpRestoreBreakPointEx(&ManipulateState, &Data, Context);
1460  break;
1461 
1462  case DbgKdCauseBugCheckApi:
1463 
1464  /* Crash the system */
1465  KdpCauseBugCheck(&ManipulateState);
1466  break;
1467 
1468  case DbgKdSwitchProcessor:
1469 
1470  /* TODO */
1471  KdpDprintf("Processor Switch support is unimplemented!\n");
1472  KdpNotSupported(&ManipulateState);
1473  break;
1474 
1475  case DbgKdPageInApi:
1476 
1477  /* TODO */
1478  KdpDprintf("Page-In support is unimplemented!\n");
1479  KdpNotSupported(&ManipulateState);
1480  break;
1481 
1483 
1484  /* Read from the specified MSR */
1485  KdpReadMachineSpecificRegister(&ManipulateState, &Data, Context);
1486  break;
1487 
1489 
1490  /* Write to the specified MSR */
1491  KdpWriteMachineSpecificRegister(&ManipulateState, &Data, Context);
1492  break;
1493 
1494  case DbgKdSearchMemoryApi:
1495 
1496  /* Search memory */
1497  KdpSearchMemory(&ManipulateState, &Data, Context);
1498  break;
1499 
1500  case DbgKdGetBusDataApi:
1501 
1502  /* Read from the bus */
1503  KdpGetBusData(&ManipulateState, &Data, Context);
1504  break;
1505 
1506  case DbgKdSetBusDataApi:
1507 
1508  /* Write to the bus */
1509  KdpSetBusData(&ManipulateState, &Data, Context);
1510  break;
1511 
1513 
1514  /* Check for memory corruption in the lower 4 GB */
1515  KdpCheckLowMemory(&ManipulateState);
1516  break;
1517 
1519 
1520  /* Just clear the counter */
1522  break;
1523 
1524  case DbgKdFillMemoryApi:
1525 
1526  /* Fill memory */
1527  KdpFillMemory(&ManipulateState, &Data, Context);
1528  break;
1529 
1530  case DbgKdQueryMemoryApi:
1531 
1532  /* Query memory */
1533  KdpQueryMemory(&ManipulateState, Context);
1534  break;
1535 
1536  case DbgKdSwitchPartition:
1537 
1538  /* TODO */
1539  KdpDprintf("Partition Switch support is unimplemented!\n");
1540  KdpNotSupported(&ManipulateState);
1541  break;
1542 
1544 
1545  /* Write the customized breakpoint */
1546  KdpWriteCustomBreakpoint(&ManipulateState, &Data, Context);
1547  break;
1548 
1549  case DbgKdGetContextExApi:
1550 
1551  /* Extended Context Get */
1552  KdpGetContextEx(&ManipulateState, &Data, Context);
1553  break;
1554 
1555  case DbgKdSetContextExApi:
1556 
1557  /* Extended Context Set */
1558  KdpSetContextEx(&ManipulateState, &Data, Context);
1559  break;
1560 
1561  /* Unsupported Messages */
1562  default:
1563 
1564  /* Send warning */
1565  KdpDprintf("Received Unrecognized API 0x%lx\n", ManipulateState.ApiNumber);
1566 
1567  /* Setup an empty message, with failure */
1568  Data.Length = 0;
1569  ManipulateState.ReturnStatus = STATUS_UNSUCCESSFUL;
1570 
1571  /* Send it */
1573  &Header,
1574  &Data,
1575  &KdpContext);
1576  break;
1577  }
1578  }
1579 }
1580 
1581 VOID
1582 NTAPI
1584  IN PKD_SYMBOLS_INFO SymbolInfo,
1585  IN BOOLEAN Unload,
1587 {
1588  PSTRING ExtraData;
1589  STRING Data, Header;
1590  DBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange;
1591  ULONG PathNameLength;
1593 
1594  /* Start wait loop */
1595  do
1596  {
1597  /* Build the architecture common parts of the message */
1598  KdpSetCommonState(DbgKdLoadSymbolsStateChange,
1599  Context,
1600  &WaitStateChange);
1601 
1602  /* Now finish creating the structure */
1603  KdpSetContextState(&WaitStateChange, Context);
1604 
1605  /* Fill out load data */
1606  WaitStateChange.u.LoadSymbols.UnloadSymbols = Unload;
1607  WaitStateChange.u.LoadSymbols.BaseOfDll = (ULONG64)(LONG_PTR)SymbolInfo->BaseOfDll;
1608  WaitStateChange.u.LoadSymbols.ProcessId = SymbolInfo->ProcessId;
1609  WaitStateChange.u.LoadSymbols.CheckSum = SymbolInfo->CheckSum;
1610  WaitStateChange.u.LoadSymbols.SizeOfImage = SymbolInfo->SizeOfImage;
1611 
1612  /* Check if we have a path name */
1613  if (PathName)
1614  {
1615  /* Copy it to the path buffer */
1616  KdpCopyMemoryChunks((ULONG_PTR)PathName->Buffer,
1617  KdpPathBuffer,
1618  PathName->Length,
1619  0,
1621  &PathNameLength);
1622 
1623  /* Null terminate */
1624  KdpPathBuffer[PathNameLength++] = ANSI_NULL;
1625 
1626  /* Set the path length */
1627  WaitStateChange.u.LoadSymbols.PathNameLength = PathNameLength;
1628 
1629  /* Set up the data */
1630  Data.Buffer = KdpPathBuffer;
1631  Data.Length = (USHORT)PathNameLength;
1632  ExtraData = &Data;
1633  }
1634  else
1635  {
1636  /* No name */
1637  WaitStateChange.u.LoadSymbols.PathNameLength = 0;
1638  ExtraData = NULL;
1639  }
1640 
1641  /* Setup the header */
1642  Header.Length = sizeof(DBGKD_ANY_WAIT_STATE_CHANGE);
1643  Header.Buffer = (PCHAR)&WaitStateChange;
1644 
1645  /* Send the packet */
1646  Status = KdpSendWaitContinue(PACKET_TYPE_KD_STATE_CHANGE64,
1647  &Header,
1648  ExtraData,
1649  Context);
1650  } while (Status == ContinueProcessorReselected);
1651 }
1652 
1653 VOID
1654 NTAPI
1656  IN PSTRING CommandString,
1658 {
1659  STRING Header, Data;
1660  DBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange;
1661  ULONG Length, ActualLength, TotalLength;
1663 
1664  /* Start wait loop */
1665  do
1666  {
1667  /* Build the architecture common parts of the message */
1668  KdpSetCommonState(DbgKdCommandStringStateChange,
1669  Context,
1670  &WaitStateChange);
1671 
1672  /* Set the context */
1673  KdpSetContextState(&WaitStateChange, Context);
1674 
1675  /* Clear the command string structure */
1676  KdpZeroMemory(&WaitStateChange.u.CommandString,
1677  sizeof(DBGKD_COMMAND_STRING));
1678 
1679  /* Normalize name string to max */
1680  Length = min(128 - 1, NameString->Length);
1681 
1682  /* Copy it to the message buffer */
1683  KdpCopyMemoryChunks((ULONG_PTR)NameString->Buffer,
1685  Length,
1686  0,
1688  &ActualLength);
1689 
1690  /* Null terminate and calculate the total length */
1691  TotalLength = ActualLength;
1693 
1694  /* Check if the command string is too long */
1695  Length = CommandString->Length;
1696  if (Length > (PACKET_MAX_SIZE -
1698  {
1699  /* Use maximum possible size */
1700  Length = (PACKET_MAX_SIZE -
1702  }
1703 
1704  /* Copy it to the message buffer */
1705  KdpCopyMemoryChunks((ULONG_PTR)CommandString->Buffer,
1707  Length,
1708  0,
1710  &ActualLength);
1711 
1712  /* Null terminate and calculate the total length */
1713  TotalLength += ActualLength;
1715 
1716  /* Now set up the header and the data */
1717  Header.Length = sizeof(DBGKD_ANY_WAIT_STATE_CHANGE);
1718  Header.Buffer = (PCHAR)&WaitStateChange;
1719  Data.Length = (USHORT)TotalLength;
1720  Data.Buffer = KdpMessageBuffer;
1721 
1722  /* Send State Change packet and wait for a reply */
1723  Status = KdpSendWaitContinue(PACKET_TYPE_KD_STATE_CHANGE64,
1724  &Header,
1725  &Data,
1726  Context);
1727  } while (Status == ContinueProcessorReselected);
1728 }
1729 
1730 BOOLEAN
1731 NTAPI
1734  IN BOOLEAN SecondChanceException)
1735 {
1736  STRING Header, Data;
1737  DBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange;
1739 
1740  /* Start report loop */
1741  do
1742  {
1743  /* Build the architecture common parts of the message */
1744  KdpSetCommonState(DbgKdExceptionStateChange, Context, &WaitStateChange);
1745 
1746 #if !defined(_WIN64)
1747 
1748  /* Convert it and copy it over */
1749  ExceptionRecord32To64((PEXCEPTION_RECORD32)ExceptionRecord,
1750  &WaitStateChange.u.Exception.ExceptionRecord);
1751 
1752 #else
1753 
1754  /* Just copy it directly, no need to convert */
1755  KdpMoveMemory(&WaitStateChange.u.Exception.ExceptionRecord,
1756  ExceptionRecord,
1757  sizeof(EXCEPTION_RECORD));
1758 
1759 #endif
1760 
1761  /* Set the First Chance flag */
1762  WaitStateChange.u.Exception.FirstChance = !SecondChanceException;
1763 
1764  /* Now finish creating the structure */
1765  KdpSetContextState(&WaitStateChange, Context);
1766 
1767  /* Setup the actual header to send to KD */
1768  Header.Length = sizeof(DBGKD_ANY_WAIT_STATE_CHANGE);
1769  Header.Buffer = (PCHAR)&WaitStateChange;
1770 
1771  /* Setup the trace data */
1772  DumpTraceData(&Data);
1773 
1774  /* Send State Change packet and wait for a reply */
1775  Status = KdpSendWaitContinue(PACKET_TYPE_KD_STATE_CHANGE64,
1776  &Header,
1777  &Data,
1778  Context);
1779  } while (Status == ContinueProcessorReselected);
1780 
1781  /* Return */
1782  return Status;
1783 }
1784 
1785 VOID
1786 NTAPI
1791 {
1792  LONG OldSlip, NewSlip, PendingSlip;
1793 
1794  /* Get the current pending slip */
1795  PendingSlip = KdpTimeSlipPending;
1796  do
1797  {
1798  /* Save the old value and either disable or enable it now. */
1799  OldSlip = PendingSlip;
1800  NewSlip = OldSlip > 1 ? 1 : 0;
1801 
1802  /* Try to change the value */
1804  NewSlip,
1805  OldSlip) != OldSlip);
1806 
1807  /* If the New Slip value is 1, then do the Time Slipping */
1809 }
1810 
1811 VOID
1812 NTAPI
1814 {
1815  KIRQL OldIrql;
1817 
1818  /* Update the System time from the CMOS */
1822 
1823  /* Check if we have a registered Time Slip Event and signal it */
1827 
1828  /* Delay the DPC until it runs next time */
1829  DueTime.QuadPart = -1800000000;
1831 }
1832 
1833 BOOLEAN
1834 NTAPI
1835 KdpSwitchProcessor(IN PEXCEPTION_RECORD ExceptionRecord,
1837  IN BOOLEAN SecondChanceException)
1838 {
1839  BOOLEAN Status;
1840 
1841  /* Save the port data */
1842  KdSave(FALSE);
1843 
1844  /* Report a state change */
1845  Status = KdpReportExceptionStateChange(ExceptionRecord,
1846  ContextRecord,
1847  SecondChanceException);
1848 
1849  /* Restore the port data and return */
1850  KdRestore(FALSE);
1851  return Status;
1852 }
1853 
1855 NTAPI
1856 KdpQueryPerformanceCounter(IN PKTRAP_FRAME TrapFrame)
1857 {
1858  LARGE_INTEGER Null = {{0}};
1859 
1860  /* Check if interrupts were disabled */
1861  if (!KeGetTrapFrameInterruptState(TrapFrame))
1862  {
1863  /* Nothing to return */
1864  return Null;
1865  }
1866 
1867  /* Otherwise, do the call */
1869 }
1870 
1871 BOOLEAN
1872 NTAPI
1873 KdEnterDebugger(IN PKTRAP_FRAME TrapFrame,
1874  IN PKEXCEPTION_FRAME ExceptionFrame)
1875 {
1876  BOOLEAN Enable;
1877 
1878  /* Check if we have a trap frame */
1879  if (TrapFrame)
1880  {
1881  /* Calculate the time difference for the enter */
1882  KdTimerStop = KdpQueryPerformanceCounter(TrapFrame);
1885  }
1886  else
1887  {
1888  /* No trap frame, so can't calculate */
1889  KdTimerStop.QuadPart = 0;
1890  }
1891 
1892  /* Save the current IRQL */
1893  KeGetCurrentPrcb()->DebuggerSavedIRQL = KeGetCurrentIrql();
1894 
1895  /* Freeze all CPUs */
1896  Enable = KeFreezeExecution(TrapFrame, ExceptionFrame);
1897 
1898  /* Lock the port, save the state and set debugger entered */
1900  KdSave(FALSE);
1902 
1903  /* Check freeze flag */
1904  if (KiFreezeFlag & 1)
1905  {
1906  /* Print out errror */
1907  KdpDprintf("FreezeLock was jammed! Backup SpinLock was used!\n");
1908  }
1909 
1910  /* Check processor state */
1911  if (KiFreezeFlag & 2)
1912  {
1913  /* Print out errror */
1914  KdpDprintf("Some processors not frozen in debugger!\n");
1915  }
1916 
1917  /* Make sure we acquired the port */
1918  if (!KdpPortLocked) KdpDprintf("Port lock was not acquired!\n");
1919 
1920  /* Return if interrupts needs to be re-enabled */
1921  return Enable;
1922 }
1923 
1924 VOID
1925 NTAPI
1927 {
1928  ULONG TimeSlip;
1929 
1930  /* Restore the state and unlock the port */
1931  KdRestore(FALSE);
1933 
1934  /* Unfreeze the CPUs */
1936 
1937  /* Compare time with the one from KdEnterDebugger */
1938  if (!KdTimerStop.QuadPart)
1939  {
1940  /* We didn't get a trap frame earlier in so never got the time */
1942  }
1943  else
1944  {
1945  /* Query the timer */
1947  }
1948 
1949  /* Check if a Time Slip was on queue */
1951  if (TimeSlip == 1)
1952  {
1953  /* Queue a DPC for the time slip */
1955  KeInsertQueueDpc(&KdpTimeSlipDpc, NULL, NULL); // FIXME: this can trigger context switches!
1956  }
1957 }
1958 
1959 NTSTATUS
1960 NTAPI
1962 {
1963  KIRQL OldIrql;
1964 
1965 #if defined(__GNUC__)
1966  /* Make gcc happy */
1968 #endif
1969 
1970  /* Check if enabling the debugger is blocked */
1971  if (KdBlockEnable)
1972  {
1973  /* It is, fail the enable */
1974  return STATUS_ACCESS_DENIED;
1975  }
1976 
1977  /* Check if we need to acquire the lock */
1978  if (NeedLock)
1979  {
1980  /* Lock the port */
1982  KdpPortLock();
1983  }
1984 
1985  /* Check if we're not disabled */
1986  if (!KdDisableCount)
1987  {
1988  /* Check if we had locked the port before */
1989  if (NeedLock)
1990  {
1991  /* Do the unlock */
1993  KdpPortUnlock();
1994 
1995  /* Fail: We're already enabled */
1996  return STATUS_INVALID_PARAMETER;
1997  }
1998  else
1999  {
2000  /*
2001  * This can only happen if we are called from a bugcheck
2002  * and were never initialized, so initialize the debugger now.
2003  */
2004  KdInitSystem(0, NULL);
2005 
2006  /* Return success since we initialized */
2007  return STATUS_SUCCESS;
2008  }
2009  }
2010 
2011  /* Decrease the disable count */
2012  if (!(--KdDisableCount))
2013  {
2014  /* We're now enabled again! Were we enabled before, too? */
2015  if (KdPreviouslyEnabled)
2016  {
2017  /* Reinitialize the Debugger */
2018  KdInitSystem(0, NULL);
2020  }
2021  }
2022 
2023  /* Check if we had locked the port before */
2024  if (NeedLock)
2025  {
2026  /* Yes, now unlock it */
2028  KdpPortUnlock();
2029  }
2030 
2031  /* We're done */
2032  return STATUS_SUCCESS;
2033 }
2034 
2035 NTSTATUS
2036 NTAPI
2038 {
2039  KIRQL OldIrql;
2040  NTSTATUS Status;
2041 
2042 #if defined(__GNUC__)
2043  /* Make gcc happy */
2045 #endif
2046 
2047  /*
2048  * If enabling the debugger is blocked
2049  * then there is nothing to disable (duh)
2050  */
2051  if (KdBlockEnable)
2052  {
2053  /* Fail */
2054  return STATUS_ACCESS_DENIED;
2055  }
2056 
2057  /* Check if we need to acquire the lock */
2058  if (NeedLock)
2059  {
2060  /* Lock the port */
2062  KdpPortLock();
2063  }
2064 
2065  /* Check if we're not disabled */
2066  if (!KdDisableCount)
2067  {
2068  /* Check if the debugger was never actually initialized */
2069  if (!(KdDebuggerEnabled) && !(KdPitchDebugger))
2070  {
2071  /* It wasn't, so don't re-enable it later */
2073  }
2074  else
2075  {
2076  /* It was, so we will re-enable it later */
2078  }
2079 
2080  /* Check if we were called from the exported API and are enabled */
2081  if ((NeedLock) && (KdPreviouslyEnabled))
2082  {
2083  /* Check if it is safe to disable the debugger */
2084  Status = KdpAllowDisable();
2085  if (!NT_SUCCESS(Status))
2086  {
2087  /* Release the lock and fail */
2089  KdpPortUnlock();
2090  return Status;
2091  }
2092  }
2093 
2094  /* Only disable the debugger if it is enabled */
2095  if (KdDebuggerEnabled)
2096  {
2097  /*
2098  * Disable the debugger; suspend breakpoints
2099  * and reset the debug stub
2100  */
2103 
2104  /* We are disabled now */
2106  SharedUserData->KdDebuggerEnabled = FALSE;
2107  }
2108  }
2109 
2110  /* Increment the disable count */
2111  KdDisableCount++;
2112 
2113  /* Check if we had locked the port before */
2114  if (NeedLock)
2115  {
2116  /* Yes, now unlock it */
2118  KdpPortUnlock();
2119  }
2120 
2121  /* We're done */
2122  return STATUS_SUCCESS;
2123 }
2124 
2125 #endif // _WINKD_
2126 
2127 /* PUBLIC FUNCTIONS **********************************************************/
2128 
2129 #ifdef _WINKD_
2130 
2131 /*
2132  * @implemented
2133  */
2134 NTSTATUS
2135 NTAPI
2137 {
2138  /* Use the internal routine */
2140 }
2141 
2142 /*
2143  * @implemented
2144  */
2145 NTSTATUS
2146 NTAPI
2148 {
2149  /* Use the internal routine */
2151 }
2152 
2153 /*
2154  * @unimplemented
2155  */
2156 NTSTATUS
2157 NTAPI
2166 {
2167  /* Handle some internal commands */
2168  switch (Command)
2169  {
2170 #if DBG
2171  case ' soR': /* ROS-INTERNAL */
2172  {
2173  switch ((ULONG_PTR)InputBuffer)
2174  {
2175  case 0x21: // DumpAllThreads:
2177  break;
2178 
2179  case 0x22: // DumpUserThreads:
2181  break;
2182 
2183  case 0x24: // KdSpare3:
2185  break;
2186 
2187  default:
2188  break;
2189  }
2190  return STATUS_SUCCESS;
2191  }
2192 
2193  /* Special case for stack frame dumps */
2194  case 'DsoR':
2195  {
2197  break;
2198  }
2199 #endif
2200  default:
2201  break;
2202  }
2203 
2204  /* Local kernel debugging is not yet supported */
2205  DbgPrint("KdSystemDebugControl is unimplemented!\n");
2206  return STATUS_NOT_IMPLEMENTED;
2207 }
2208 
2209 /*
2210  * @implemented
2211  */
2212 NTSTATUS
2213 NTAPI
2214 KdChangeOption(IN KD_OPTION Option,
2215  IN ULONG InBufferBytes OPTIONAL,
2216  IN PVOID InBuffer,
2217  IN ULONG OutBufferBytes OPTIONAL,
2218  OUT PVOID OutBuffer,
2219  OUT PULONG OutBufferNeeded OPTIONAL)
2220 {
2221  /* Fail if there is no debugger */
2222  if (KdPitchDebugger)
2223  {
2224  /* No debugger, no options */
2225  return STATUS_DEBUGGER_INACTIVE;
2226  }
2227 
2228  /* Do we recognize this option? */
2229  if (Option != KD_OPTION_SET_BLOCK_ENABLE)
2230  {
2231  /* We don't, clear the output length and fail */
2232  if (OutBufferNeeded) *OutBufferNeeded = 0;
2234  }
2235 
2236  /* Verify parameters */
2237  if ((InBufferBytes != sizeof(BOOLEAN)) ||
2238  (OutBufferBytes != 0) ||
2239  (OutBuffer != NULL))
2240  {
2241  /* Invalid parameters for this option, fail */
2242  return STATUS_INVALID_PARAMETER;
2243  }
2244 
2245  /*
2246  * Check if the high bit is set, meaning we don't
2247  * allow the debugger to be enabled
2248  */
2249  if (KdBlockEnable & 0x80)
2250  {
2251  /* Fail regardless of what state the caller tried to set */
2252  return STATUS_ACCESS_VIOLATION;
2253  }
2254 
2255  /* Set the new block enable state */
2256  KdBlockEnable = *(PBOOLEAN)InBuffer;
2257 
2258  /* No output buffer required for this option */
2259  if (OutBufferNeeded) *OutBufferNeeded = 0;
2260 
2261  /* We are done */
2262  return STATUS_SUCCESS;
2263 }
2264 
2265 /*
2266  * @implemented
2267  */
2268 NTSTATUS
2269 NTAPI
2271 {
2272  /* Check what power state this is */
2273  if (NewState == PowerDeviceD0)
2274  {
2275  /* Wake up the debug port */
2276  KdD0Transition();
2277  return STATUS_SUCCESS;
2278  }
2279  else if ((NewState == PowerDeviceD1) ||
2280  (NewState == PowerDeviceD2) ||
2281  (NewState == PowerDeviceD3))
2282  {
2283  /* Power down the debug port */
2284  KdD3Transition();
2285  return STATUS_SUCCESS;
2286  }
2287  else
2288  {
2289  /* Invalid state! */
2291  }
2292 }
2293 
2294 /*
2295  * @implemented
2296  */
2297 BOOLEAN
2298 NTAPI
2300 {
2301  BOOLEAN Enable, DebuggerNotPresent;
2302 
2303  /* Check if the debugger is completely disabled */
2304  if (KdPitchDebugger)
2305  {
2306  /* Don't try to refresh then, fail early */
2307  return TRUE;
2308  }
2309 
2310  /* Enter the debugger */
2312 
2313  /*
2314  * Attempt to send a string to the debugger
2315  * to refresh the connection state.
2316  */
2317  KdpDprintf("KDTARGET: Refreshing KD connection\n");
2318 
2319  /* Save the state while we are holding the lock */
2320  DebuggerNotPresent = KdDebuggerNotPresent;
2321 
2322  /* Exit the debugger and return the state */
2324  return DebuggerNotPresent;
2325 }
2326 
2327 #endif // _WINKD_
2328 
2329 /*
2330  * @implemented
2331  */
2332 NTSTATUS
2333 NTAPI
2336  _In_ ULONG Level)
2337 {
2338  PULONG Mask;
2339 
2340  /* Check if the ID fits in the component table */
2342  {
2343  /* It does, so get the mask from there */
2344  Mask = KdComponentTable[ComponentId];
2345  }
2346  else if (ComponentId == MAXULONG)
2347  {
2348  /*
2349  * This is the internal ID used for DbgPrint messages without ID
2350  * and Level. Use the system-wide mask for those.
2351  */
2352  Mask = &Kd_WIN2000_Mask;
2353  }
2354  else
2355  {
2356 #if (NTDDI_VERSION >= NTDDI_VISTA)
2357  /* Use the default component ID */
2358  Mask = &Kd_DEFAULT_Mask;
2359  // Level = DPFLTR_INFO_LEVEL; // Override the Level.
2360 #else
2361  /* Invalid ID, fail */
2363 #endif
2364  }
2365 
2366  /* Convert Level to bit field if required */
2367  if (Level < 32) Level = 1 << Level;
2368  Level &= ~DPFLTR_MASK;
2369 
2370  /* Determine if this Level is filtered out */
2371  if ((Kd_WIN2000_Mask & Level) || (*Mask & Level))
2372  {
2373  /* This mask will get through to the debugger */
2374  return (NTSTATUS)TRUE;
2375  }
2376  else
2377  {
2378  /* This mask is filtered out */
2379  return (NTSTATUS)FALSE;
2380  }
2381 }
2382 
2383 /*
2384  * @implemented
2385  */
2386 NTSTATUS
2387 NTAPI
2390  _In_ ULONG Level,
2391  _In_ BOOLEAN State)
2392 {
2393  PULONG Mask;
2394 
2395  /* Modifying debug filters requires the debug privilege */
2397  {
2398  /* Fail */
2399  return STATUS_ACCESS_DENIED;
2400  }
2401 
2402  /* Check if the ID fits in the component table */
2404  {
2405  /* It does, so get the mask from there */
2406  Mask = KdComponentTable[ComponentId];
2407  }
2408  else if (ComponentId == MAXULONG)
2409  {
2410  /*
2411  * This is the internal ID used for DbgPrint messages without ID
2412  * and Level. Use the system-wide mask for those.
2413  */
2414  Mask = &Kd_WIN2000_Mask;
2415  }
2416  else
2417  {
2418 #if (NTDDI_VERSION >= NTDDI_VISTA)
2419  /* Use the default component ID */
2420  Mask = &Kd_DEFAULT_Mask;
2421 #else
2422  /* Invalid ID, fail */
2424 #endif
2425  }
2426 
2427  /* Convert Level to bit field if required */
2428  if (Level < 32) Level = 1 << Level;
2429  Level &= ~DPFLTR_MASK;
2430 
2431  /* Set or remove the Level */
2432  if (State)
2433  *Mask |= Level;
2434  else
2435  *Mask &= ~Level;
2436 
2437  return STATUS_SUCCESS;
2438 }
NTSTATUS NTAPI KdpCopyMemoryChunks(_In_ ULONG64 Address, _In_ PVOID Buffer, _In_ ULONG TotalSize, _In_ ULONG ChunkSize, _In_ ULONG Flags, _Out_opt_ PULONG ActualSize)
Definition: kdapi.c:50
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
signed char * PCHAR
Definition: retypes.h:7
#define DbgKdSetBusDataApi
Definition: windbgkd.h:108
BOOLEAN KdpContextSent
Definition: kddata.c:69
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
#define KeRosDumpStackFrames(Frames, Count)
Definition: gdidebug.h:11
#define IN
Definition: typedefs.h:38
#define DbgKdWriteVirtualMemoryApi
Definition: windbgkd.h:75
DBGKD_CONTINUE Continue
Definition: windbgkd.h:779
#define DbgKdWritePhysicalMemoryApi
Definition: windbgkd.h:88
#define DbgKdReadControlSpaceApi
Definition: windbgkd.h:81
VOID NTAPI ExReleaseTimeRefreshLock(VOID)
Definition: time.c:83
LARGE_INTEGER NTAPI KeQueryPerformanceCounter(IN PLARGE_INTEGER PerformanceFreq)
Definition: timer.c:138
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
DBGKD_GET_VERSION64 KdVersionBlock
Definition: kddata.c:470
IN PVOID IN PVOID IN USHORT Version
Definition: pci.h:359
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
union _DBGKD_ANY_WAIT_STATE_CHANGE::@3418 u
#define DbgKdGetVersionApi
Definition: windbgkd.h:96
PKDEBUG_ROUTINE KiDebugRoutine
Definition: kdmain.c:448
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define DbgPrint
Definition: loader.c:25
#define DbgKdCauseBugCheckApi
Definition: windbgkd.h:99
const LUID SeDebugPrivilege
Definition: priv.c:41
NTSTATUS NTAPI NtSetDebugFilterState(_In_ ULONG ComponentId, _In_ ULONG Level, _In_ BOOLEAN State)
Definition: kdapi.c:2388
NTSTATUS NTAPI KdDisableDebugger(VOID)
Definition: kdmain.c:339
VOID NTAPI Unload(PDRIVER_OBJECT DriverObject)
Definition: csqtest.c:160
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ LARGE_INTEGER DueTime
Definition: kefuncs.h:524
#define DbgKdRebootApi
Definition: windbgkd.h:85
VOID NTAPI MmDumpArmPfnDatabase(IN BOOLEAN StatusOnly)
Definition: mminit.c:1474
#define DBGKD_QUERY_MEMORY_VIRTUAL
Definition: windbgkd.h:159
#define DbgKdReadVirtualMemoryApi
Definition: windbgkd.h:74
VOID NTAPI KeThawExecution(IN BOOLEAN Enable)
Definition: freeze.c:46
#define DbgKdSetContextExApi
Definition: windbgkd.h:116
BOOLEAN NTAPI KdpStub(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ContextRecord, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN SecondChanceException)
Definition: kdtrap.c:266
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:724
LONG NTSTATUS
Definition: precomp.h:26
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:140
BOOLEAN NTAPI MmIsSessionAddress(IN PVOID Address)
Definition: session.c:49
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
#define DbgKdFillMemoryApi
Definition: windbgkd.h:111
ULONG KdComponentTableSize
Definition: kddata.c:459
#define DbgKdClearSpecialCallsApi
Definition: windbgkd.h:91
BOOLEAN KdPreviouslyEnabled
#define DPFLTR_MASK
Definition: kdtypes.h:34
KDP_STATUS NTAPI KdReceivePacket(IN ULONG PacketType, OUT PSTRING MessageHeader, OUT PSTRING MessageData, OUT PULONG DataLength, IN OUT PKD_CONTEXT KdContext)
Definition: kddll.c:80
static ULONGLONG Memory
Definition: CcMapData_drv.c:35
KSPIN_LOCK KdpDebuggerLock
Definition: kddata.c:67
enum _KCONTINUE_STATUS KCONTINUE_STATUS
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ ULONG _In_ ULONG OutputBufferLength
Definition: fltkernel.h:1374
#define InterlockedCompareExchange
Definition: interlocked.h:104
BOOLEAN KdPitchDebugger
Definition: kdmain.c:52
NTSTATUS NTAPI KdpSysWriteBusData(IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN ULONG Offset, IN PVOID Buffer, IN ULONG Length, OUT PULONG ActualLength)
Definition: kdx64.c:148
BOOLEAN KdBlockEnable
BOOLEAN NTAPI SeSinglePrivilegeCheck(IN LUID PrivilegeValue, IN KPROCESSOR_MODE PreviousMode)
Definition: priv.c:524
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3066
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
#define DbgKdWriteCustomBreakpointApi
Definition: windbgkd.h:114
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char UINT32 ComponentId
Definition: acpixf.h:1270
#define DbgKdWriteControlSpaceApi
Definition: windbgkd.h:82
NTSTATUS NTAPI KdpAllowDisable(VOID)
Definition: kdx64.c:364
#define DbgKdExceptionStateChange
Definition: windbgkd.h:59
Definition: shell.h:41
VOID NTAPI KdExitDebugger(IN BOOLEAN Enable)
Definition: kdmain.c:317
#define DbgKdContinueApi
Definition: windbgkd.h:80
NTSTATUS NTAPI KdRestore(IN BOOLEAN SleepTransition)
Definition: kdcom.c:110
_In_ ULONG TotalLength
Definition: usbdlib.h:145
#define PACKET_MAX_SIZE
Definition: windbgkd.h:18
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define DBGKD_CACHING_UNCACHED
Definition: windbgkd.h:191
struct _CONTEXT CONTEXT
CHAR KdpMessageBuffer[0x1000]
Definition: kddata.c:131
#define DbgKdWriteMachineSpecificRegister
Definition: windbgkd.h:103
#define DbgKdRestoreBreakPointApi
Definition: windbgkd.h:79
LARGE_INTEGER KdTimerDifference
Definition: kddata.c:126
#define DbgKdWriteBreakPointExApi
Definition: windbgkd.h:97
CHAR InputBuffer[80]
Definition: conmgr.c:33
VOID NTAPI PspDumpThreads(BOOLEAN SystemThreads)
NTSTATUS NTAPI KdPowerTransition(ULONG PowerState)
Definition: kdmain.c:406
NTSTATUS NTAPI KdpSysCheckLowMemory(IN ULONG Flags)
Definition: kdx64.c:356
uint32_t ULONG_PTR
Definition: typedefs.h:63
LONG KdpTimeSlipPending
Definition: kddata.c:123
#define DBGKD_QUERY_MEMORY_KERNEL
Definition: windbgkd.h:162
UCHAR KIRQL
Definition: env_spec_w32.h:591
LARGE_INTEGER KdTimerStart
Definition: kd64.h:548
#define KdPacketNeedsResend
Definition: kddll.h:7
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define DbgKdSwitchProcessor
Definition: windbgkd.h:100
NTSTATUS NTAPI NtQueryDebugFilterState(_In_ ULONG ComponentId, _In_ ULONG Level)
Definition: kdapi.c:2334
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define DbgKdWriteIoSpaceApi
Definition: windbgkd.h:84
#define ANSI_NULL
CHAR KdpPathBuffer[0x1000]
Definition: kddata.c:132
Definition: Header.h:8
_Inout_ PUCHAR _In_ PUCHAR _Out_ PUCHAR _Out_ PULONG ChunkSize
Definition: rtlfuncs.h:2276
#define DbgKdSwitchPartition
Definition: windbgkd.h:113
long LONG
Definition: pedump.c:60
NTSTATUS NTAPI KdpSysWriteIoSpace(IN ULONG InterfaceType, IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize)
Definition: kdx64.c:300
static __inline VOID NTAPI ExceptionRecord32To64(IN PEXCEPTION_RECORD32 Ex32, OUT PEXCEPTION_RECORD64 Ex64)
Definition: windbgkd.h:897
NTSTATUS NTAPI KdpSysReadControlSpace(IN ULONG Processor, IN ULONG64 BaseAddress, IN PVOID Buffer, IN ULONG Length, OUT PULONG ActualLength)
Definition: kdx64.c:162
BOOLEAN KdEnteredDebugger
Definition: kdmain.c:49
BOOLEAN NTAPI KeFreezeExecution(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
Definition: freeze.c:26
BOOLEAN SendPacket(PSERIAL_PACKET p)
Definition: serial.c:225
DBGKD_LOAD_SYMBOLS64 LoadSymbols
Definition: windbgkd.h:489
unsigned char BOOLEAN
enum _SYSDBG_COMMAND SYSDBG_COMMAND
BOOLEAN NTAPI KdpDeleteBreakpoint(IN ULONG BpEntry)
Definition: kdbreak.c:311
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
WORK_QUEUE_ITEM KdpTimeSlipWorkItem
Definition: kddata.c:122
BOOLEAN KdDebuggerEnabled
Definition: kdmain.c:48
#define _Out_
Definition: no_sal2.h:323
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
VOID NTAPI KdpPortUnlock(VOID)
Definition: kdlock.c:27
ULONG64 TargetBaseAddress
Definition: windbgkd.h:525
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1507
Definition: bufpool.h:45
#define MMDBG_COPY_WRITE
Definition: mm.h:53
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID OutputBuffer
Definition: iofuncs.h:713
void * PVOID
Definition: retypes.h:9
#define DbgKdClearAllInternalBreakpointsApi
Definition: windbgkd.h:110
#define KeGetContextPc(Context)
Definition: ke.h:124
NTSTATUS NTAPI KdChangeOption(IN KD_OPTION Option, IN ULONG InBufferLength OPTIONAL, IN PVOID InBuffer, IN ULONG OutBufferLength OPTIONAL, OUT PVOID OutBuffer, OUT PULONG OutBufferRequiredLength OPTIONAL)
Definition: kdmain.c:417
BOOLEAN NTAPI KdRefreshDebuggerNotPresent(VOID)
Definition: kdmain.c:326
KD_CONTEXT KdpContext
Definition: kddata.c:65
#define PCHAR
Definition: match.c:90
NTSTATUS NTAPI KdSystemDebugControl(IN SYSDBG_COMMAND Command, IN PVOID InputBuffer, IN ULONG InputBufferLength, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength, IN OUT PULONG ReturnLength, IN KPROCESSOR_MODE PreviousMode)
Definition: kdmain.c:433
#define DBGKD_CACHING_CACHED
Definition: windbgkd.h:190
enum _DEVICE_POWER_STATE DEVICE_POWER_STATE
NTSTATUS NTAPI KdD0Transition(VOID)
Definition: kdcom.c:88
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
#define DbgKdCommandStringStateChange
Definition: windbgkd.h:61
#define _Out_opt_
Definition: no_sal2.h:339
ULONG KiFreezeFlag
Definition: cpu.c:38
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define DbgKdReadPhysicalMemoryApi
Definition: windbgkd.h:87
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:524
#define DbgKdWriteIoSpaceExtendedApi
Definition: windbgkd.h:95
NTSTATUS NTAPI KdpSysWriteMsr(IN ULONG Msr, IN PLARGE_INTEGER MsrValue)
Definition: kdx64.c:115
NTSTATUS NTAPI KdEnableDebuggerWithLock(IN BOOLEAN NeedLock)
Definition: kdmain.c:361
ULONG64 TargetBaseAddress
Definition: windbgkd.h:511
DBGKD_COMMAND_STRING CommandString
Definition: windbgkd.h:490
#define KdPacketTimedOut
Definition: kddll.h:6
#define DbgKdLoadSymbolsStateChange
Definition: windbgkd.h:60
NTSTATUS NTAPI KdDisableDebuggerWithLock(IN BOOLEAN NeedLock)
ULONG Kd_WIN2000_Mask
Definition: kddata.c:147
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MMDBG_COPY_UNCACHED
Definition: mm.h:57
#define DbgKdQueryMemoryApi
Definition: windbgkd.h:112
#define DbgKdSearchMemoryApi
Definition: windbgkd.h:106
NTSTATUS NTAPI KdpSysReadBusData(IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN ULONG Offset, IN PVOID Buffer, IN ULONG Length, OUT PULONG ActualLength)
Definition: kdx64.c:134
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define DbgKdGetContextApi
Definition: windbgkd.h:76
VOID NTAPI KdpMoveMemory(_In_ PVOID Destination, _In_ PVOID Source, _In_ SIZE_T Length)
Definition: kdapi.c:22
struct _DBGKD_ANY_WAIT_STATE_CHANGE DBGKD_ANY_WAIT_STATE_CHANGE
PULONG KdComponentTable[MAX_KD_COMPONENT_TABLE_ENTRIES]
Definition: kddata.c:303
BOOLEAN NTAPI ExAcquireTimeRefreshLock(IN BOOLEAN Wait)
Definition: time.c:51
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2922
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
VOID NTAPI KdpReportLoadSymbolsStateChange(IN PSTRING PathName, IN PKD_SYMBOLS_INFO SymbolInfo, IN BOOLEAN Unload, IN OUT PCONTEXT Context)
VOID NTAPI HalReturnToFirmware(IN FIRMWARE_REENTRY Action)
Definition: reboot.c:22
#define _Inout_
Definition: no_sal2.h:244
VOID NTAPI KdpSuspendAllBreakPoints(VOID)
Definition: kdbreak.c:407
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
NTSTATUS NTAPI KdpSysReadIoSpace(IN ULONG InterfaceType, IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 IoAddress, IN PVOID DataValue, IN ULONG DataSize, OUT PULONG ActualDataSize)
Definition: kdarm.c:108
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
NTSTATUS NTAPI KdEnableDebugger(VOID)
Definition: kdmain.c:371
#define DbgKdGetContextExApi
Definition: windbgkd.h:115
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
std::wstring STRING
Definition: fontsub.cpp:33
#define PACKET_TYPE_KD_STATE_MANIPULATE
Definition: windbgkd.h:43
_IRQL_requires_same_ _In_ PVOID _Inout_ struct _CONTEXT * ContextRecord
Definition: ntbasedef.h:661
VOID NTAPI KdpSysGetVersion(IN PDBGKD_GET_VERSION64 Version)
unsigned __int64 ULONG64
Definition: imports.h:198
#define SharedUserData
EXCEPTION_RECORD64 ExceptionRecord
Definition: windbgkd.h:303
char * PBOOLEAN
Definition: retypes.h:11
union _DBGKD_MANIPULATE_STATE64::@3426 u
#define DbgKdGetBusDataApi
Definition: windbgkd.h:107
#define PACKET_TYPE_KD_STATE_CHANGE64
Definition: windbgkd.h:48
ULONG KdDisableCount
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:226
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
Definition: ketypes.h:687
#define DbgKdReadMachineSpecificRegister
Definition: windbgkd.h:102
#define STATUS_INVALID_PARAMETER_1
Definition: ntstatus.h:461
ULONG LowPart
Definition: typedefs.h:104
#define DbgKdContinueApi2
Definition: windbgkd.h:86
#define STATUS_DEBUGGER_INACTIVE
Definition: debugger.c:30
#define DbgKdSetContextApi
Definition: windbgkd.h:77
#define DbgKdCheckLowMemoryApi
Definition: windbgkd.h:109
NTSTATUS NTAPI KdpSysWriteControlSpace(IN ULONG Processor, IN ULONG64 BaseAddress, IN PVOID Buffer, IN ULONG Length, OUT PULONG ActualLength)
Definition: kdx64.c:213
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
LARGE_INTEGER KdTimerStop
Definition: kddata.c:126
VOID NTAPI ExUpdateSystemTimeFromCmos(IN BOOLEAN UpdateInterruptTime, IN ULONG MaxSepInSeconds)
Definition: time.c:217
_In_opt_ PENTER_STATE_SYSTEM_HANDLER _In_opt_ PVOID _In_ LONG _In_opt_ LONG volatile * Number
Definition: ntpoapi.h:204
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ ULONG InputBufferLength
Definition: fltkernel.h:1372
ULONG NTAPI KdpAddBreakpoint(IN PVOID Address)
Definition: kdbreak.c:20
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
Status
Definition: gdiplustypes.h:24
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
#define MAXULONG
Definition: typedefs.h:250
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
KDPC KdpTimeSlipDpc
Definition: kddata.c:120
#define _In_
Definition: no_sal2.h:204
#define DBGKD_QUERY_MEMORY_EXECUTE
Definition: windbgkd.h:169
#define MMDBG_COPY_WRITE_COMBINED
Definition: mm.h:58
_In_ PLIST_ENTRY _In_ PSTRING _In_ USHORT _In_opt_ PSTRING _In_opt_ PSTRING _In_ ULONG _In_ ULONG _In_opt_ PVOID TargetContext
Definition: fsrtlfuncs.h:738
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define DbgKdQuerySpecialCallsApi
Definition: windbgkd.h:89
#define DbgKdRestoreBreakPointExApi
Definition: windbgkd.h:98
NTSTATUS NTAPI MmDbgCopyMemory(IN ULONG64 Address, IN PVOID Buffer, IN ULONG Size, IN ULONG Flags)
Definition: mmdbg.c:126
#define DBGKD_QUERY_MEMORY_PROCESS
Definition: windbgkd.h:160
#define DbgKdSetSpecialCallApi
Definition: windbgkd.h:90
#define InterlockedIncrement
Definition: armddk.h:53
ULONG TraceDataBufferPosition
Definition: kddata.c:115
#define DbgKdWriteBreakPointApi
Definition: windbgkd.h:78
NTSTATUS NTAPI KdD3Transition(VOID)
Definition: kdcom.c:95
#define DBGKD_QUERY_MEMORY_SESSION
Definition: windbgkd.h:161
#define DBGKD_CACHING_WRITE_COMBINED
Definition: windbgkd.h:192
BOOLEAN NTAPI KdInitSystem(ULONG Reserved, PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: kdinit.c:169
#define KeGetTrapFrameInterruptState(TrapFrame)
Definition: ke.h:170
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
unsigned short USHORT
Definition: pedump.c:61
#define MMDBG_COPY_PHYSICAL
Definition: mm.h:54
VOID NTAPI KdpSetContextState(IN PDBGKD_ANY_WAIT_STATE_CHANGE WaitStateChange, IN PCONTEXT Context)
Definition: kdx64.c:66
PKEVENT KdpTimeSlipEvent
Definition: kddata.c:124
ULONG Kd_DEFAULT_Mask
Definition: kddata.c:249
PKPRCB KiProcessorBlock[]
Definition: krnlinit.c:32
#define MMDBG_COPY_UNSAFE
Definition: mm.h:55
ULONG KDSTATUS
Definition: kddll.h:4
#define MMDBG_COPY_MAX_SIZE
Definition: mm.h:63
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
NTSTATUS ContinueStatus
Definition: windbgkd.h:559
#define DBGKD_QUERY_MEMORY_READ
Definition: windbgkd.h:167
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
PVOID MmHighestUserAddress
Definition: rtlcompat.c:29
ULONG TraceDataBuffer[40]
Definition: kddata.c:114
#define KdpDprintf
Definition: mmdbg.c:19
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
DBGKM_EXCEPTION64 Exception
Definition: windbgkd.h:488
VOID NTAPI KdpTimeSlipDpcRoutine(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
VOID NTAPI KdpTimeSlipWork(IN PVOID Context)
BOOLEAN KdpPortLocked
Definition: kddata.c:66
#define DbgKdSetInternalBreakPointApi
Definition: windbgkd.h:92
USHORT KeProcessorLevel
Definition: krnlinit.c:20
#define OUT
Definition: typedefs.h:39
static BOOL SendData(PINFO pInfo)
Definition: ntpclient.c:76
#define DbgKdReadIoSpaceExtendedApi
Definition: windbgkd.h:94
#define MMDBG_COPY_CACHED
Definition: mm.h:56
struct tagContext Context
Definition: acpixf.h:1030
BOOLEAN NTAPI KdpReportExceptionStateChange(IN PEXCEPTION_RECORD ExceptionRecord, IN OUT PCONTEXT Context, IN BOOLEAN SecondChanceException)
unsigned int ULONG
Definition: retypes.h:1
uint32_t * PULONG_PTR
Definition: typedefs.h:63
BOOLEAN NTAPI KdEnterDebugger(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
Definition: kdmain.c:309
enum _KD_OPTION KD_OPTION
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
KSPIN_LOCK KdpTimeSlipEventLock
Definition: kddata.c:125
NTSTATUS NTAPI KdSave(IN BOOLEAN SleepTransition)
Definition: kdcom.c:102
VOID NTAPI KdpPortLock(VOID)
Definition: kdlock.c:19
BOOLEAN NTAPI KdpSwitchProcessor(IN PEXCEPTION_RECORD ExceptionRecord, IN OUT PCONTEXT ContextRecord, IN BOOLEAN SecondChanceException)
#define DBGKD_MAXSTREAM
Definition: windbgkd.h:19
VOID NTAPI KdpZeroMemory(_In_ PVOID Destination, _In_ SIZE_T Length)
Definition: kdapi.c:37
#define KeGetCurrentThread
Definition: hal.h:44
BOOLEAN FASTCALL KeTryToAcquireSpinLockAtDpcLevel(IN OUT PKSPIN_LOCK SpinLock)
Definition: spinlock.c:303
return STATUS_SUCCESS
Definition: btrfs.c:2938
BOOLEAN NTAPI KdpDeleteBreakpointRange(IN PVOID Base, IN PVOID Limit)
Definition: kdbreak.c:340
VOID NTAPI KdpGetStateChange(IN PDBGKD_MANIPULATE_STATE64 State, IN PCONTEXT Context)
Definition: kdx64.c:22
KTIMER KdpTimeSlipTimer
Definition: kddata.c:121
#define DbgKdReadIoSpaceApi
Definition: windbgkd.h:83
VOID NTAPI KdSendPacket(IN ULONG PacketType, IN PSTRING MessageHeader, IN PSTRING MessageData, IN OUT PKD_CONTEXT KdContext)
Definition: kddll.c:314
#define DbgKdPageInApi
Definition: windbgkd.h:101
#define DbgKdGetInternalBreakPointApi
Definition: windbgkd.h:93
VOID NTAPI KdpRestoreAllBreakpoints(VOID)
Definition: kdbreak.c:368
BOOLEAN KdDebuggerNotPresent
Definition: kdmain.c:50
struct _DBGKD_MANIPULATE_STATE64 DBGKD_MANIPULATE_STATE64
FORCEINLINE VOID KeSweepICache(IN PVOID BaseAddress, IN SIZE_T FlushSize)
Definition: ke.h:217
NTSTATUS ContinueStatus
Definition: windbgkd.h:565
ULONG KdpNumInternalBreakpoints
Definition: kddata.c:104
VOID NTAPI KdpReportCommandStringStateChange(IN PSTRING NameString, IN PSTRING CommandString, IN OUT PCONTEXT Context)
LONGLONG QuadPart
Definition: typedefs.h:112
NTSTATUS NTAPI KdpSysReadMsr(IN ULONG Msr, OUT PLARGE_INTEGER MsrValue)
Definition: kdx64.c:96
DBGKD_CONTINUE2 Continue2
Definition: windbgkd.h:780
#define DBGKD_QUERY_MEMORY_WRITE
Definition: windbgkd.h:168
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:675