KD64 Compatibility Bringup:
[reactos.git] / reactos / ntoskrnl / kd64 / kdapi.c
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 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 /* PRIVATE FUNCTIONS *********************************************************/
16
17 VOID
18 NTAPI
19 KdpQueryMemory(IN PDBGKD_MANIPULATE_STATE64 State,
20 IN PCONTEXT Context)
21 {
22 PDBGKD_QUERY_MEMORY Memory = &State->u.QueryMemory;
23 STRING Header;
24 NTSTATUS Status = STATUS_SUCCESS;
25
26 /* Validate the address space */
27 if (Memory->AddressSpace == DBGKD_QUERY_MEMORY_VIRTUAL)
28 {
29 /* Check if this is process memory */
30 if ((PVOID)(ULONG_PTR)Memory->Address < MmHighestUserAddress)
31 {
32 /* It is */
33 Memory->AddressSpace = DBGKD_QUERY_MEMORY_PROCESS;
34 }
35 else
36 {
37 /* FIXME: Check if it's session space */
38 Memory->AddressSpace = DBGKD_QUERY_MEMORY_KERNEL;
39 }
40
41 /* Set flags */
42 Memory->Flags = DBGKD_QUERY_MEMORY_READ |
43 DBGKD_QUERY_MEMORY_WRITE |
44 DBGKD_QUERY_MEMORY_EXECUTE;
45 }
46 else
47 {
48 /* Invalid */
49 Status = STATUS_INVALID_PARAMETER;
50 }
51
52 /* Return structure */
53 State->ReturnStatus = Status;
54 Memory->Reserved = 0;
55
56 /* Build header */
57 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
58 Header.Buffer = (PCHAR)State;
59
60 /* Send the packet */
61 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
62 &Header,
63 NULL,
64 &KdpContext);
65 }
66
67 VOID
68 NTAPI
69 KdpWriteBreakpoint(IN PDBGKD_MANIPULATE_STATE64 State,
70 IN PSTRING Data,
71 IN PCONTEXT Context)
72 {
73 PDBGKD_WRITE_BREAKPOINT64 Breakpoint = &State->u.WriteBreakPoint;
74 STRING Header;
75
76 /* Build header */
77 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
78 Header.Buffer = (PCHAR)State;
79 ASSERT(Data->Length == 0);
80
81 /* Create the breakpoint */
82 Breakpoint->BreakPointHandle =
83 KdpAddBreakpoint((PVOID)(ULONG_PTR)Breakpoint->BreakPointAddress);
84 if (!Breakpoint->BreakPointHandle)
85 {
86 /* We failed */
87 State->ReturnStatus = STATUS_UNSUCCESSFUL;
88 }
89 else
90 {
91 /* Success! */
92 State->ReturnStatus = STATUS_SUCCESS;
93 }
94
95 /* Send the packet */
96 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
97 &Header,
98 NULL,
99 &KdpContext);
100 }
101
102 VOID
103 NTAPI
104 DumpTraceData(IN PSTRING TraceData)
105 {
106 /* Update the buffer */
107 TraceDataBuffer[0] = TraceDataBufferPosition;
108
109 /* Setup the trace data */
110 TraceData->Length = TraceDataBufferPosition * sizeof(ULONG);
111 TraceData->Buffer = (PCHAR)TraceDataBuffer;
112
113 /* Reset the buffer location */
114 TraceDataBufferPosition = 1;
115 }
116
117 VOID
118 NTAPI
119 KdpSetCommonState(IN ULONG NewState,
120 IN PCONTEXT Context,
121 IN PDBGKD_WAIT_STATE_CHANGE64 WaitStateChange)
122 {
123 USHORT InstructionCount;
124 BOOLEAN HadBreakpoints;
125
126 /* Setup common stuff available for all CPU architectures */
127 WaitStateChange->NewState = NewState;
128 WaitStateChange->ProcessorLevel = KeProcessorLevel;
129 WaitStateChange->Processor = (USHORT)KeGetCurrentPrcb()->Number;
130 WaitStateChange->NumberProcessors = (ULONG)KeNumberProcessors;
131 WaitStateChange->Thread = (ULONG64)(LONG_PTR)KeGetCurrentThread();
132 WaitStateChange->ProgramCounter = (ULONG64)(LONG_PTR)KeGetContextPc(Context);
133
134 /* Zero out the Control Report */
135 RtlZeroMemory(&WaitStateChange->ControlReport,
136 sizeof(DBGKD_CONTROL_REPORT));
137
138 /* Now copy the instruction stream and set the count */
139 RtlCopyMemory(&WaitStateChange->ControlReport.InstructionStream[0],
140 (PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter,
141 DBGKD_MAXSTREAM);
142 InstructionCount = DBGKD_MAXSTREAM;
143 WaitStateChange->ControlReport.InstructionCount = InstructionCount;
144
145 /* Clear all the breakpoints in this region */
146 HadBreakpoints =
147 KdpDeleteBreakpointRange((PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter,
148 (PVOID)((ULONG_PTR)WaitStateChange->ProgramCounter +
149 WaitStateChange->ControlReport.InstructionCount - 1));
150 if (HadBreakpoints)
151 {
152 /* Copy the instruction stream again, this time without breakpoints */
153 RtlCopyMemory(&WaitStateChange->ControlReport.InstructionStream[0],
154 (PVOID)(ULONG_PTR)WaitStateChange->ProgramCounter,
155 WaitStateChange->ControlReport.InstructionCount);
156 }
157 }
158
159 VOID
160 NTAPI
161 KdpGetVersion(IN PDBGKD_MANIPULATE_STATE64 State)
162 {
163 STRING Header;
164
165 /* Fill out the header */
166 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
167 Header.Buffer = (PCHAR)State;
168
169 /* Get the version block */
170 KdpSysGetVersion(&State->u.GetVersion64);
171
172 /* Fill out the state */
173 State->ApiNumber = DbgKdGetVersionApi;
174 State->ReturnStatus = STATUS_SUCCESS;
175
176 /* Send the packet */
177 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
178 &Header,
179 NULL,
180 &KdpContext);
181 }
182
183 VOID
184 NTAPI
185 KdpReadVirtualMemory(IN PDBGKD_MANIPULATE_STATE64 State,
186 IN PSTRING Data,
187 IN PCONTEXT Context)
188 {
189 STRING Header;
190 ULONG Length = State->u.ReadMemory.TransferCount;
191 NTSTATUS Status = STATUS_SUCCESS;
192
193 /* Validate length */
194 if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64)))
195 {
196 /* Overflow, set it to maximum possible */
197 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64);
198 }
199
200 #if 0
201 if (!MmIsAddressValid((PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress))
202 {
203 KdpDprintf("Tried to read invalid address %p\n",
204 (PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress);
205 while (TRUE);
206 }
207 #endif
208
209 if (!State->u.ReadMemory.TargetBaseAddress)
210 {
211 Length = 0;
212 Status = STATUS_UNSUCCESSFUL;
213 }
214 else
215 {
216 RtlCopyMemory(Data->Buffer,
217 (PVOID)(ULONG_PTR)State->u.ReadMemory.TargetBaseAddress,
218 Length);
219 }
220
221 /* Fill out the header */
222 Data->Length = Length;
223 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
224 Header.Buffer = (PCHAR)State;
225
226 /* Fill out the state */
227 State->ReturnStatus = Status;
228 State->u.ReadMemory.ActualBytesRead = Length;
229
230 /* Send the packet */
231 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
232 &Header,
233 Data,
234 &KdpContext);
235 }
236
237 VOID
238 NTAPI
239 KdpReadControlSpace(IN PDBGKD_MANIPULATE_STATE64 State,
240 IN PSTRING Data,
241 IN PCONTEXT Context)
242 {
243 PDBGKD_READ_MEMORY64 ReadMemory = &State->u.ReadMemory;
244 STRING Header;
245 ULONG Length;
246
247 /* Setup the header */
248 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
249 Header.Buffer = (PCHAR)State;
250 ASSERT(Data->Length == 0);
251
252 /* Check the length requested */
253 Length = ReadMemory->TransferCount;
254 if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64)))
255 {
256 /* Use maximum allowed */
257 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64);
258 }
259
260 /* Call the internal routine */
261 State->ReturnStatus = KdpSysReadControlSpace(State->Processor,
262 ReadMemory->TargetBaseAddress,
263 Data->Buffer,
264 Length,
265 &Length);
266
267 /* Return the actual length read */
268 Data->Length = ReadMemory->ActualBytesRead = Length;
269
270 /* Send the reply */
271 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
272 &Header,
273 Data,
274 &KdpContext);
275 }
276
277 VOID
278 NTAPI
279 KdpWriteControlSpace(IN PDBGKD_MANIPULATE_STATE64 State,
280 IN PSTRING Data,
281 IN PCONTEXT Context)
282 {
283 PDBGKD_WRITE_MEMORY64 WriteMemory = &State->u.WriteMemory;
284 STRING Header;
285 ULONG Length;
286
287 /* Setup the header */
288 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
289 Header.Buffer = (PCHAR)State;
290
291 /* Call the internal routine */
292 State->ReturnStatus = KdpSysWriteControlSpace(State->Processor,
293 WriteMemory->TargetBaseAddress,
294 Data->Buffer,
295 Data->Length,
296 &Length);
297
298 /* Return the length written */
299 WriteMemory->ActualBytesWritten = Length;
300
301 /* Send the reply */
302 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
303 &Header,
304 Data,
305 &KdpContext);
306 }
307
308 VOID
309 NTAPI
310 KdpRestoreBreakpoint(IN PDBGKD_MANIPULATE_STATE64 State,
311 IN PSTRING Data,
312 IN PCONTEXT Context)
313 {
314 PDBGKD_RESTORE_BREAKPOINT RestoreBp = &State->u.RestoreBreakPoint;
315 STRING Header;
316
317 /* Fill out the header */
318 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
319 Header.Buffer = (PCHAR)State;
320 ASSERT(Data->Length == 0);
321
322 /* Get the version block */
323 if (KdpDeleteBreakpoint(RestoreBp->BreakPointHandle))
324 {
325 /* We're all good */
326 State->ReturnStatus = STATUS_SUCCESS;
327 }
328 else
329 {
330 /* We failed */
331 State->ReturnStatus = STATUS_UNSUCCESSFUL;
332 }
333
334 /* Send the packet */
335 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
336 &Header,
337 NULL,
338 &KdpContext);
339 }
340
341 VOID
342 NTAPI
343 KdpGetContext(IN PDBGKD_MANIPULATE_STATE64 State,
344 IN PSTRING Data,
345 IN PCONTEXT Context)
346 {
347 STRING Header;
348 PVOID ControlStart;
349
350 /* Setup the header */
351 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
352 Header.Buffer = (PCHAR)State;
353 ASSERT(Data->Length == 0);
354
355 /* Make sure that this is a valid request */
356 if (State->Processor < KeNumberProcessors)
357 {
358 /* Check if the request is for this CPU */
359 if (State->Processor == KeGetCurrentPrcb()->Number)
360 {
361 /* We're just copying our own context */
362 ControlStart = Context;
363 }
364 else
365 {
366 /* SMP not yet handled */
367 KdpDprintf("SMP UNHANDLED\n");
368 ControlStart = NULL;
369 while (TRUE);
370 }
371
372 /* Copy the memory */
373 RtlCopyMemory(Data->Buffer, ControlStart, sizeof(CONTEXT));
374 Data->Length = sizeof(CONTEXT);
375
376 /* Finish up */
377 State->ReturnStatus = STATUS_SUCCESS;
378 }
379 else
380 {
381 /* Invalid request */
382 State->ReturnStatus = STATUS_UNSUCCESSFUL;
383 }
384
385 /* Send the reply */
386 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
387 &Header,
388 Data,
389 &KdpContext);
390 }
391
392 VOID
393 NTAPI
394 KdpSetContext(IN PDBGKD_MANIPULATE_STATE64 State,
395 IN PSTRING Data,
396 IN PCONTEXT Context)
397 {
398 STRING Header;
399 PVOID ControlStart;
400
401 /* Setup the header */
402 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
403 Header.Buffer = (PCHAR)State;
404 ASSERT(Data->Length == sizeof(CONTEXT));
405
406 /* Make sure that this is a valid request */
407 if (State->Processor < KeNumberProcessors)
408 {
409 /* Check if the request is for this CPU */
410 if (State->Processor == KeGetCurrentPrcb()->Number)
411 {
412 /* We're just copying our own context */
413 ControlStart = Context;
414 }
415 else
416 {
417 /* SMP not yet handled */
418 KdpDprintf("SMP UNHANDLED\n");
419 ControlStart = NULL;
420 while (TRUE);
421 }
422
423 /* Copy the memory */
424 RtlCopyMemory(ControlStart, Data->Buffer, sizeof(CONTEXT));
425
426 /* Finish up */
427 State->ReturnStatus = STATUS_SUCCESS;
428 }
429 else
430 {
431 /* Invalid request */
432 State->ReturnStatus = STATUS_UNSUCCESSFUL;
433 }
434
435 /* Send the reply */
436 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
437 &Header,
438 Data,
439 &KdpContext);
440 }
441
442 VOID
443 NTAPI
444 KdpCauseBugCheck(IN PDBGKD_MANIPULATE_STATE64 State)
445 {
446 /* Crash with the special code */
447 KeBugCheck(MANUALLY_INITIATED_CRASH);
448 }
449
450 VOID
451 NTAPI
452 KdpReadMachineSpecificRegister(IN PDBGKD_MANIPULATE_STATE64 State,
453 IN PSTRING Data,
454 IN PCONTEXT Context)
455 {
456 STRING Header;
457 PDBGKD_READ_WRITE_MSR ReadMsr = &State->u.ReadWriteMsr;
458 LARGE_INTEGER MsrValue;
459
460 /* Setup the header */
461 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
462 Header.Buffer = (PCHAR)State;
463 ASSERT(Data->Length == 0);
464
465 /* Call the internal routine */
466 State->ReturnStatus = KdpSysReadMsr(ReadMsr->Msr,
467 &MsrValue);
468
469 /* Return the data */
470 ReadMsr->DataValueLow = MsrValue.LowPart;
471 ReadMsr->DataValueHigh = MsrValue.HighPart;
472
473 /* Send the reply */
474 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
475 &Header,
476 NULL,
477 &KdpContext);
478 }
479
480 VOID
481 NTAPI
482 KdpWriteMachineSpecificRegister(IN PDBGKD_MANIPULATE_STATE64 State,
483 IN PSTRING Data,
484 IN PCONTEXT Context)
485 {
486 STRING Header;
487 PDBGKD_READ_WRITE_MSR WriteMsr = &State->u.ReadWriteMsr;
488 LARGE_INTEGER MsrValue;
489
490 /* Setup the header */
491 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
492 Header.Buffer = (PCHAR)State;
493 ASSERT(Data->Length == 0);
494
495 /* Call the internal routine */
496 MsrValue.LowPart = WriteMsr->DataValueLow;
497 MsrValue.HighPart = WriteMsr->DataValueHigh;
498 State->ReturnStatus = KdpSysWriteMsr(WriteMsr->Msr,
499 &MsrValue);
500
501 /* Send the reply */
502 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
503 &Header,
504 NULL,
505 &KdpContext);
506 }
507
508 VOID
509 NTAPI
510 KdpGetBusData(IN PDBGKD_MANIPULATE_STATE64 State,
511 IN PSTRING Data,
512 IN PCONTEXT Context)
513 {
514 STRING Header;
515 PDBGKD_GET_SET_BUS_DATA GetBusData = &State->u.GetSetBusData;
516 ULONG Length;
517
518 /* Setup the header */
519 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
520 Header.Buffer = (PCHAR)State;
521 ASSERT(Data->Length == 0);
522
523 /* Check the length requested */
524 Length = GetBusData->Length;
525 if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64)))
526 {
527 /* Use maximum allowed */
528 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE64);
529 }
530
531 /* Call the internal routine */
532 State->ReturnStatus = KdpSysReadBusData(GetBusData->BusDataType,
533 GetBusData->BusNumber,
534 GetBusData->SlotNumber,
535 Data->Buffer,
536 GetBusData->Offset,
537 Length,
538 &Length);
539
540 /* Return the actual length read */
541 Data->Length = GetBusData->Length = Length;
542
543 /* Send the reply */
544 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
545 &Header,
546 Data,
547 &KdpContext);
548 }
549
550 VOID
551 NTAPI
552 KdpSetBusData(IN PDBGKD_MANIPULATE_STATE64 State,
553 IN PSTRING Data,
554 IN PCONTEXT Context)
555 {
556 STRING Header;
557 PDBGKD_GET_SET_BUS_DATA SetBusData = &State->u.GetSetBusData;
558 ULONG Length;
559
560 /* Setup the header */
561 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
562 Header.Buffer = (PCHAR)State;
563
564 /* Call the internal routine */
565 State->ReturnStatus = KdpSysWriteBusData(SetBusData->BusDataType,
566 SetBusData->BusNumber,
567 SetBusData->SlotNumber,
568 Data->Buffer,
569 SetBusData->Offset,
570 SetBusData->Length,
571 &Length);
572
573 /* Return the actual length written */
574 SetBusData->Length = Length;
575
576 /* Send the reply */
577 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
578 &Header,
579 Data,
580 &KdpContext);
581 }
582
583 VOID
584 NTAPI
585 KdpReadIoSpace(IN PDBGKD_MANIPULATE_STATE64 State,
586 IN PSTRING Data,
587 IN PCONTEXT Context)
588 {
589 STRING Header;
590 PDBGKD_READ_WRITE_IO64 ReadIo = &State->u.ReadWriteIo;
591
592 /* Setup the header */
593 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
594 Header.Buffer = (PCHAR)State;
595 ASSERT(Data->Length == 0);
596
597 /*
598 * Clear the value so 1 or 2 byte reads
599 * don't leave the higher bits unmodified
600 */
601 ReadIo->DataValue = 0;
602
603 /* Call the internal routine */
604 State->ReturnStatus = KdpSysReadIoSpace(Isa,
605 0,
606 1,
607 ReadIo->IoAddress,
608 &ReadIo->DataValue,
609 ReadIo->DataSize,
610 &ReadIo->DataSize);
611
612 /* Send the reply */
613 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
614 &Header,
615 NULL,
616 &KdpContext);
617 }
618
619 VOID
620 NTAPI
621 KdpWriteIoSpace(IN PDBGKD_MANIPULATE_STATE64 State,
622 IN PSTRING Data,
623 IN PCONTEXT Context)
624 {
625 STRING Header;
626 PDBGKD_READ_WRITE_IO64 WriteIo = &State->u.ReadWriteIo;
627
628 /* Setup the header */
629 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
630 Header.Buffer = (PCHAR)State;
631 ASSERT(Data->Length == 0);
632
633 /* Call the internal routine */
634 State->ReturnStatus = KdpSysWriteIoSpace(Isa,
635 0,
636 1,
637 WriteIo->IoAddress,
638 &WriteIo->DataValue,
639 WriteIo->DataSize,
640 &WriteIo->DataSize);
641
642 /* Send the reply */
643 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
644 &Header,
645 NULL,
646 &KdpContext);
647 }
648
649 VOID
650 NTAPI
651 KdpReadIoSpaceExtended(IN PDBGKD_MANIPULATE_STATE64 State,
652 IN PSTRING Data,
653 IN PCONTEXT Context)
654 {
655 STRING Header;
656 PDBGKD_READ_WRITE_IO_EXTENDED64 ReadIoExtended = &State->u.
657 ReadWriteIoExtended;
658
659 /* Setup the header */
660 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
661 Header.Buffer = (PCHAR)State;
662 ASSERT(Data->Length == 0);
663
664 /*
665 * Clear the value so 1 or 2 byte reads
666 * don't leave the higher bits unmodified
667 */
668 ReadIoExtended->DataValue = 0;
669
670 /* Call the internal routine */
671 State->ReturnStatus = KdpSysReadIoSpace(ReadIoExtended->InterfaceType,
672 ReadIoExtended->BusNumber,
673 ReadIoExtended->AddressSpace,
674 ReadIoExtended->IoAddress,
675 &ReadIoExtended->DataValue,
676 ReadIoExtended->DataSize,
677 &ReadIoExtended->DataSize);
678
679 /* Send the reply */
680 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
681 &Header,
682 NULL,
683 &KdpContext);
684 }
685
686 VOID
687 NTAPI
688 KdpWriteIoSpaceExtended(IN PDBGKD_MANIPULATE_STATE64 State,
689 IN PSTRING Data,
690 IN PCONTEXT Context)
691 {
692 STRING Header;
693 PDBGKD_READ_WRITE_IO_EXTENDED64 WriteIoExtended = &State->u.
694 ReadWriteIoExtended;
695
696 /* Setup the header */
697 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
698 Header.Buffer = (PCHAR)State;
699 ASSERT(Data->Length == 0);
700
701 /* Call the internal routine */
702 State->ReturnStatus = KdpSysReadIoSpace(WriteIoExtended->InterfaceType,
703 WriteIoExtended->BusNumber,
704 WriteIoExtended->AddressSpace,
705 WriteIoExtended->IoAddress,
706 &WriteIoExtended->DataValue,
707 WriteIoExtended->DataSize,
708 &WriteIoExtended->DataSize);
709
710 /* Send the reply */
711 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
712 &Header,
713 NULL,
714 &KdpContext);
715 }
716
717 VOID
718 NTAPI
719 KdpCheckLowMemory(IN PDBGKD_MANIPULATE_STATE64 State)
720 {
721 STRING Header;
722
723 /* Setup the header */
724 Header.Length = sizeof(DBGKD_MANIPULATE_STATE64);
725 Header.Buffer = (PCHAR)State;
726
727 /* Call the internal routine */
728 State->ReturnStatus = KdpSysCheckLowMemory(0x4);
729
730 /* Send the reply */
731 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
732 &Header,
733 NULL,
734 &KdpContext);
735 }
736
737 KCONTINUE_STATUS
738 NTAPI
739 KdpSendWaitContinue(IN ULONG PacketType,
740 IN PSTRING SendHeader,
741 IN PSTRING SendData OPTIONAL,
742 IN OUT PCONTEXT Context)
743 {
744 STRING Data, Header;
745 DBGKD_MANIPULATE_STATE64 ManipulateState;
746 ULONG Length;
747 KDSTATUS RecvCode;
748
749 /* Setup the Manipulate State structure */
750 Header.MaximumLength = sizeof(DBGKD_MANIPULATE_STATE64);
751 Header.Buffer = (PCHAR)&ManipulateState;
752 Data.MaximumLength = sizeof(KdpMessageBuffer);
753 Data.Buffer = KdpMessageBuffer;
754 //KdpContextSent = FALSE;
755
756 SendPacket:
757 /* Send the Packet */
758 KdSendPacket(PacketType, SendHeader, SendData, &KdpContext);
759
760 /* If the debugger isn't present anymore, just return success */
761 if (KdDebuggerNotPresent) return ContinueSuccess;
762
763 /* Main processing Loop */
764 for (;;)
765 {
766 /* Receive Loop */
767 do
768 {
769 /* Wait to get a reply to our packet */
770 RecvCode = KdReceivePacket(PACKET_TYPE_KD_STATE_MANIPULATE,
771 &Header,
772 &Data,
773 &Length,
774 &KdpContext);
775
776 /* If we got a resend request, do it */
777 if (RecvCode == KdPacketNeedsResend) goto SendPacket;
778 } while (RecvCode == KdPacketTimedOut);
779
780 /* Now check what API we got */
781 switch (ManipulateState.ApiNumber)
782 {
783 case DbgKdReadVirtualMemoryApi:
784
785 /* Read virtual memory */
786 KdpReadVirtualMemory(&ManipulateState, &Data, Context);
787 break;
788
789 case DbgKdWriteVirtualMemoryApi:
790
791 /* FIXME: TODO */
792 KdpDprintf("DbgKdWriteVirtualMemoryApi called\n");
793 while (TRUE);
794 break;
795
796 case DbgKdGetContextApi:
797
798 /* Get the current context */
799 KdpGetContext(&ManipulateState, &Data, Context);
800 break;
801
802 case DbgKdSetContextApi:
803
804 /* Set a new context */
805 KdpSetContext(&ManipulateState, &Data, Context);
806 break;
807
808 case DbgKdWriteBreakPointApi:
809
810 /* Write the breakpoint */
811 KdpWriteBreakpoint(&ManipulateState, &Data, Context);
812 break;
813
814 case DbgKdRestoreBreakPointApi:
815
816 /* Restore the breakpoint */
817 KdpRestoreBreakpoint(&ManipulateState, &Data, Context);
818 break;
819
820 case DbgKdContinueApi:
821
822 /* Simply continue */
823 return NT_SUCCESS(ManipulateState.u.Continue.ContinueStatus);
824
825 case DbgKdReadControlSpaceApi:
826
827 /* Read control space */
828 KdpReadControlSpace(&ManipulateState, &Data, Context);
829 break;
830
831 case DbgKdWriteControlSpaceApi:
832
833 /* Write control space */
834 KdpWriteControlSpace(&ManipulateState, &Data, Context);
835 break;
836
837 case DbgKdReadIoSpaceApi:
838
839 /* Read I/O Space */
840 KdpReadIoSpace(&ManipulateState, &Data, Context);
841 break;
842
843 case DbgKdWriteIoSpaceApi:
844
845 /* Write I/O Space */
846 KdpWriteIoSpace(&ManipulateState, &Data, Context);
847 break;
848
849 case DbgKdRebootApi:
850
851 /* Reboot the system */
852 HalReturnToFirmware(HalRebootRoutine);
853 break;
854
855 case DbgKdContinueApi2:
856
857 /* Check if caller reports success */
858 if (NT_SUCCESS(ManipulateState.u.Continue2.ContinueStatus))
859 {
860 /* Update the state */
861 KdpGetStateChange(&ManipulateState, Context);
862 return ContinueSuccess;
863 }
864 else
865 {
866 /* Return an error */
867 return ContinueError;
868 }
869 break;
870
871 case DbgKdReadPhysicalMemoryApi:
872
873 /* FIXME: TODO */
874 KdpDprintf("DbgKdReadPhysicalMemoryApi called for address %I64X\n",
875 ManipulateState.u.ReadMemory.TargetBaseAddress);
876 goto Hack;
877 while (TRUE);
878 break;
879
880 case DbgKdWritePhysicalMemoryApi:
881
882 /* FIXME: TODO */
883 KdpDprintf("DbgKdWritePhysicalMemoryApi called\n");
884 while (TRUE);
885 break;
886
887 case DbgKdQuerySpecialCallsApi:
888
889 /* FIXME: TODO */
890 KdpDprintf("DbgKdQuerySpecialCallsApi called\n");
891 while (TRUE);
892 break;
893
894 case DbgKdSetSpecialCallApi:
895
896 /* FIXME: TODO */
897 KdpDprintf("DbgKdSetSpecialCallApi called\n");
898 while (TRUE);
899 break;
900
901 case DbgKdClearSpecialCallsApi:
902
903 /* FIXME: TODO */
904 KdpDprintf("DbgKdClearSpecialCallsApi called\n");
905 while (TRUE);
906 break;
907
908 case DbgKdSetInternalBreakPointApi:
909
910 /* FIXME: TODO */
911 KdpDprintf("DbgKdSetInternalBreakPointApi called\n");
912 while (TRUE);
913 break;
914
915 case DbgKdGetInternalBreakPointApi:
916
917 /* FIXME: TODO */
918 KdpDprintf("DbgKdGetInternalBreakPointApi called\n");
919 while (TRUE);
920 break;
921
922 case DbgKdReadIoSpaceExtendedApi:
923
924 /* Read I/O Space */
925 KdpReadIoSpaceExtended(&ManipulateState, &Data, Context);
926 break;
927
928 case DbgKdWriteIoSpaceExtendedApi:
929
930 /* Write I/O Space */
931 KdpWriteIoSpaceExtended(&ManipulateState, &Data, Context);
932 break;
933
934 case DbgKdGetVersionApi:
935
936 /* Get version data */
937 KdpGetVersion(&ManipulateState);
938 break;
939
940 case DbgKdWriteBreakPointExApi:
941
942 /* FIXME: TODO */
943 KdpDprintf("DbgKdWriteBreakPointExApi called\n");
944 while (TRUE);
945 break;
946
947 case DbgKdRestoreBreakPointExApi:
948
949 /* FIXME: TODO */
950 KdpDprintf("DbgKdRestoreBreakPointExApi called\n");
951 while (TRUE);
952 break;
953
954 case DbgKdCauseBugCheckApi:
955
956 /* Crash the system */
957 KdpCauseBugCheck(&ManipulateState);
958 break;
959
960 case DbgKdSwitchProcessor:
961
962 /* FIXME: TODO */
963 KdpDprintf("DbgKdSwitchProcessor called\n");
964 while (TRUE);
965 break;
966
967 case DbgKdPageInApi:
968
969 /* FIXME: TODO */
970 KdpDprintf("DbgKdPageInApi called\n");
971 while (TRUE);
972 break;
973
974 case DbgKdReadMachineSpecificRegister:
975
976 /* Read from the specified MSR */
977 KdpReadMachineSpecificRegister(&ManipulateState, &Data, Context);
978 break;
979
980 case DbgKdWriteMachineSpecificRegister:
981
982 /* Write to the specified MSR */
983 KdpWriteMachineSpecificRegister(&ManipulateState, &Data, Context);
984 break;
985
986 case OldVlm1:
987
988 /* FIXME: TODO */
989 KdpDprintf("OldVlm1 called\n");
990 while (TRUE);
991 break;
992
993 case OldVlm2:
994
995 /* FIXME: TODO */
996 KdpDprintf("OldVlm2 called\n");
997 while (TRUE);
998 break;
999
1000 case DbgKdSearchMemoryApi:
1001
1002 /* FIXME: TODO */
1003 KdpDprintf("DbgKdSearchMemoryApi called\n");
1004 while (TRUE);
1005 break;
1006
1007 case DbgKdGetBusDataApi:
1008
1009 /* Read from the bus */
1010 KdpGetBusData(&ManipulateState, &Data, Context);
1011 break;
1012
1013 case DbgKdSetBusDataApi:
1014
1015 /* Write to the bus */
1016 KdpSetBusData(&ManipulateState, &Data, Context);
1017 break;
1018
1019 case DbgKdCheckLowMemoryApi:
1020
1021 /* Check for memory corruption in the lower 4 GB */
1022 KdpCheckLowMemory(&ManipulateState);
1023 break;
1024
1025 case DbgKdClearAllInternalBreakpointsApi:
1026
1027 /* Just clear the counter */
1028 KdpNumInternalBreakpoints = 0;
1029 break;
1030
1031 case DbgKdFillMemoryApi:
1032
1033 /* FIXME: TODO */
1034 KdpDprintf("DbgKdFillMemoryApi called\n");
1035 while (TRUE);
1036 break;
1037
1038 case DbgKdQueryMemoryApi:
1039
1040 /* Query memory */
1041 KdpQueryMemory(&ManipulateState, Context);
1042 break;
1043
1044 case DbgKdSwitchPartition:
1045
1046 /* FIXME: TODO */
1047 KdpDprintf("DbgKdSwitchPartition called\n");
1048 while (TRUE);
1049 break;
1050
1051 /* Unsupported Message */
1052 default:
1053
1054 /* Setup an empty message, with failure */
1055 KdpDprintf("Received unknown API Number %lx\n", ManipulateState.ApiNumber);
1056 while (TRUE);
1057 Hack:
1058 Data.Length = 0;
1059 ManipulateState.ReturnStatus = STATUS_UNSUCCESSFUL;
1060
1061 /* Send it */
1062 KdSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
1063 &Header,
1064 &Data,
1065 &KdpContext);
1066 break;
1067 }
1068 }
1069 }
1070
1071 BOOLEAN
1072 NTAPI
1073 KdpReportLoadSymbolsStateChange(IN PSTRING PathName,
1074 IN PKD_SYMBOLS_INFO SymbolInfo,
1075 IN BOOLEAN Unload,
1076 IN OUT PCONTEXT Context)
1077 {
1078 PSTRING ExtraData;
1079 STRING Data, Header;
1080 DBGKD_WAIT_STATE_CHANGE64 WaitStateChange;
1081 KCONTINUE_STATUS Status;
1082
1083 /* Start wait loop */
1084 do
1085 {
1086 /* Build the architecture common parts of the message */
1087 KdpSetCommonState(DbgKdLoadSymbolsStateChange,
1088 Context,
1089 &WaitStateChange);
1090
1091 /* Now finish creating the structure */
1092 KdpSetContextState(&WaitStateChange, Context);
1093
1094 /* Fill out load data */
1095 WaitStateChange.u.LoadSymbols.UnloadSymbols = Unload;
1096 WaitStateChange.u.LoadSymbols.BaseOfDll = (ULONG64)(LONG_PTR)SymbolInfo->BaseOfDll;
1097 WaitStateChange.u.LoadSymbols.ProcessId = SymbolInfo->ProcessId;
1098 WaitStateChange.u.LoadSymbols.CheckSum = SymbolInfo->CheckSum;
1099 WaitStateChange.u.LoadSymbols.SizeOfImage = SymbolInfo->SizeOfImage;
1100
1101 /* Check if we have a symbol name */
1102 if (PathName)
1103 {
1104 /* Setup the information */
1105 WaitStateChange.u.LoadSymbols.PathNameLength = PathName->Length;
1106 RtlCopyMemory(KdpPathBuffer, PathName->Buffer, PathName->Length);
1107 Data.Buffer = KdpPathBuffer;
1108 Data.Length = WaitStateChange.u.LoadSymbols.PathNameLength;
1109 ExtraData = &Data;
1110 }
1111 else
1112 {
1113 /* No name */
1114 WaitStateChange.u.LoadSymbols.PathNameLength = 0;
1115 ExtraData = NULL;
1116 }
1117
1118 /* Setup the header */
1119 Header.Length = sizeof(DBGKD_WAIT_STATE_CHANGE64);
1120 Header.Buffer = (PCHAR)&WaitStateChange;
1121
1122 /* Send the packet */
1123 Status = KdpSendWaitContinue(PACKET_TYPE_KD_STATE_CHANGE64,
1124 &Header,
1125 ExtraData,
1126 Context);
1127 } while (Status == ContinueProcessorReselected);
1128
1129 /* Return status */
1130 return Status;
1131 }
1132
1133 BOOLEAN
1134 NTAPI
1135 KdpReportExceptionStateChange(IN PEXCEPTION_RECORD ExceptionRecord,
1136 IN OUT PCONTEXT Context,
1137 IN BOOLEAN SecondChanceException)
1138 {
1139 STRING Header, Data;
1140 DBGKD_WAIT_STATE_CHANGE64 WaitStateChange;
1141 KCONTINUE_STATUS Status;
1142
1143 /* Start report loop */
1144 do
1145 {
1146 /* Build the architecture common parts of the message */
1147 KdpSetCommonState(DbgKdExceptionStateChange, Context, &WaitStateChange);
1148
1149 /* Copy the Exception Record and set First Chance flag */
1150 CopyExceptionRecord(ExceptionRecord,
1151 &WaitStateChange.u.Exception.ExceptionRecord);
1152 WaitStateChange.u.Exception.FirstChance = !SecondChanceException;
1153
1154 /* Now finish creating the structure */
1155 KdpSetContextState(&WaitStateChange, Context);
1156
1157 /* Setup the actual header to send to KD */
1158 Header.Length = sizeof(DBGKD_WAIT_STATE_CHANGE64);
1159 Header.Buffer = (PCHAR)&WaitStateChange;
1160
1161 /* Setup the trace data */
1162 DumpTraceData(&Data);
1163
1164 /* Send State Change packet and wait for a reply */
1165 Status = KdpSendWaitContinue(PACKET_TYPE_KD_STATE_CHANGE64,
1166 &Header,
1167 &Data,
1168 Context);
1169 } while (Status == ContinueProcessorReselected);
1170
1171 /* Return */
1172 return Status;
1173 }
1174
1175 VOID
1176 NTAPI
1177 KdpTimeSlipDpcRoutine(IN PKDPC Dpc,
1178 IN PVOID DeferredContext,
1179 IN PVOID SystemArgument1,
1180 IN PVOID SystemArgument2)
1181 {
1182 LONG OldSlip, NewSlip, PendingSlip;
1183
1184 /* Get the current pending slip */
1185 PendingSlip = KdpTimeSlipPending;
1186 do
1187 {
1188 /* Save the old value and either disable or enable it now. */
1189 OldSlip = PendingSlip;
1190 NewSlip = OldSlip > 1 ? 1 : 0;
1191
1192 /* Try to change the value */
1193 } while (InterlockedCompareExchange(&KdpTimeSlipPending,
1194 NewSlip,
1195 OldSlip) != OldSlip);
1196
1197 /* If the New Slip value is 1, then do the Time Slipping */
1198 if (NewSlip) ExQueueWorkItem(&KdpTimeSlipWorkItem, DelayedWorkQueue);
1199 }
1200
1201 VOID
1202 NTAPI
1203 KdpTimeSlipWork(IN PVOID Context)
1204 {
1205 KIRQL OldIrql;
1206 LARGE_INTEGER DueTime;
1207
1208 /* Update the System time from the CMOS */
1209 ExAcquireTimeRefreshLock(FALSE);
1210 ExUpdateSystemTimeFromCmos(FALSE, 0);
1211 ExReleaseTimeRefreshLock();
1212
1213 /* Check if we have a registered Time Slip Event and signal it */
1214 KeAcquireSpinLock(&KdpTimeSlipEventLock, &OldIrql);
1215 if (KdpTimeSlipEvent) KeSetEvent(KdpTimeSlipEvent, 0, FALSE);
1216 KeReleaseSpinLock(&KdpTimeSlipEventLock, OldIrql);
1217
1218 /* Delay the DPC until it runs next time */
1219 DueTime.QuadPart = -1800000000;
1220 KeSetTimer(&KdpTimeSlipTimer, DueTime, &KdpTimeSlipDpc);
1221 }
1222
1223 BOOLEAN
1224 NTAPI
1225 KdpSwitchProcessor(IN PEXCEPTION_RECORD ExceptionRecord,
1226 IN OUT PCONTEXT ContextRecord,
1227 IN BOOLEAN SecondChanceException)
1228 {
1229 BOOLEAN Status;
1230
1231 /* Save the port data */
1232 KdSave(FALSE);
1233
1234 /* Report a state change */
1235 Status = KdpReportExceptionStateChange(ExceptionRecord,
1236 ContextRecord,
1237 SecondChanceException);
1238
1239 /* Restore the port data and return */
1240 KdRestore(FALSE);
1241 return Status;
1242 }
1243
1244 LARGE_INTEGER
1245 NTAPI
1246 KdpQueryPerformanceCounter(IN PKTRAP_FRAME TrapFrame)
1247 {
1248 LARGE_INTEGER Null = {{0}};
1249
1250 /* Check if interrupts were disabled */
1251 if (!KeGetTrapFrameInterruptState(TrapFrame))
1252 {
1253 /* Nothing to return */
1254 return Null;
1255 }
1256
1257 /* Otherwise, do the call */
1258 return KeQueryPerformanceCounter(NULL);
1259 }
1260
1261 BOOLEAN
1262 NTAPI
1263 KdEnterDebugger(IN PKTRAP_FRAME TrapFrame,
1264 IN PKEXCEPTION_FRAME ExceptionFrame)
1265 {
1266 BOOLEAN Entered;
1267
1268 /* Check if we have a trap frame */
1269 if (TrapFrame)
1270 {
1271 /* Calculate the time difference for the enter */
1272 KdTimerStop = KdpQueryPerformanceCounter(TrapFrame);
1273 KdTimerDifference.QuadPart = KdTimerStop.QuadPart -
1274 KdTimerStart.QuadPart;
1275 }
1276 else
1277 {
1278 /* No trap frame, so can't calculate */
1279 KdTimerStop.QuadPart = 0;
1280 }
1281
1282 /* Save the current IRQL */
1283 KeGetCurrentPrcb()->DebuggerSavedIRQL = KeGetCurrentIrql();
1284
1285 /* Freeze all CPUs */
1286 Entered = KeFreezeExecution(TrapFrame, ExceptionFrame);
1287
1288 /* Lock the port, save the state and set debugger entered */
1289 KdpPortLocked = KeTryToAcquireSpinLockAtDpcLevel(&KdpDebuggerLock);
1290 KdSave(FALSE);
1291 KdEnteredDebugger = TRUE;
1292
1293 /* Check freeze flag */
1294 if (KiFreezeFlag & 1)
1295 {
1296 /* Print out errror */
1297 KdpDprintf("FreezeLock was jammed! Backup SpinLock was used!\n");
1298 }
1299
1300 /* Check processor state */
1301 if (KiFreezeFlag & 2)
1302 {
1303 /* Print out errror */
1304 KdpDprintf("Some processors not frozen in debugger!\n");
1305 }
1306
1307 /* Make sure we acquired the port */
1308 if (!KdpPortLocked) KdpDprintf("Port lock was not acquired!\n");
1309
1310 /* Return enter state */
1311 return Entered;
1312 }
1313
1314 VOID
1315 NTAPI
1316 KdExitDebugger(IN BOOLEAN Entered)
1317 {
1318 ULONG TimeSlip;
1319
1320 /* Restore the state and unlock the port */
1321 KdRestore(FALSE);
1322 if (KdpPortLocked) KdpPortUnlock();
1323
1324 /* Unfreeze the CPUs */
1325 KeThawExecution(Entered);
1326
1327 /* Compare time with the one from KdEnterDebugger */
1328 if (!KdTimerStop.QuadPart)
1329 {
1330 /* We didn't get a trap frame earlier in so never got the time */
1331 KdTimerStart = KdTimerStop;
1332 }
1333 else
1334 {
1335 /* Query the timer */
1336 KdTimerStart = KeQueryPerformanceCounter(NULL);
1337 }
1338
1339 /* Check if a Time Slip was on queue */
1340 TimeSlip = InterlockedIncrement(&KdpTimeSlipPending);
1341 if (TimeSlip == 1)
1342 {
1343 /* Queue a DPC for the time slip */
1344 InterlockedIncrement(&KdpTimeSlipPending);
1345 KeInsertQueueDpc(&KdpTimeSlipDpc, NULL, NULL);
1346 }
1347 }
1348
1349 NTSTATUS
1350 NTAPI
1351 KdEnableDebuggerWithLock(IN BOOLEAN NeedLock)
1352 {
1353 KIRQL OldIrql;
1354
1355 #if defined(__GNUC__)
1356 /* Make gcc happy */
1357 OldIrql = PASSIVE_LEVEL;
1358 #endif
1359
1360 /* Check if we need to acquire the lock */
1361 if (NeedLock)
1362 {
1363 /* Lock the port */
1364 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
1365 KdpPortLock();
1366 }
1367
1368 /* Check if we're not disabled */
1369 if (!KdDisableCount)
1370 {
1371 /* Check if we had locked the port before */
1372 if (NeedLock)
1373 {
1374 /* Do the unlock */
1375 KeLowerIrql(OldIrql);
1376 KdpPortUnlock();
1377 }
1378
1379 /* Fail: We're already enabled */
1380 return STATUS_INVALID_PARAMETER;
1381 }
1382
1383 /* Decrease the disable count */
1384 if (!(--KdDisableCount))
1385 {
1386 /* We're now enabled again! Were we enabled before, too? */
1387 if (KdPreviouslyEnabled)
1388 {
1389 /* Reinitialize the Debugger */
1390 KdInitSystem(0, NULL) ;
1391 KdpRestoreAllBreakpoints();
1392 }
1393 }
1394
1395 /* Check if we had locked the port before */
1396 if (NeedLock)
1397 {
1398 /* Yes, now unlock it */
1399 KeLowerIrql(OldIrql);
1400 KdpPortUnlock();
1401 }
1402
1403 /* We're done */
1404 return STATUS_SUCCESS;
1405 }
1406
1407 /* PUBLIC FUNCTIONS **********************************************************/
1408
1409 /*
1410 * @implemented
1411 */
1412 NTSTATUS
1413 NTAPI
1414 KdEnableDebugger(VOID)
1415 {
1416 /* Use the internal routine */
1417 KdpDprintf("KdEnableDebugger called\n");
1418 while (TRUE);
1419 return KdEnableDebuggerWithLock(TRUE);
1420 }
1421
1422 /*
1423 * @unimplemented
1424 */
1425 NTSTATUS
1426 NTAPI
1427 KdSystemDebugControl(IN SYSDBG_COMMAND Command,
1428 IN PVOID InputBuffer,
1429 IN ULONG InputBufferLength,
1430 OUT PVOID OutputBuffer,
1431 IN ULONG OutputBufferLength,
1432 IN OUT PULONG ReturnLength,
1433 IN KPROCESSOR_MODE PreviousMode)
1434 {
1435 /* HACK */
1436 return STATUS_SUCCESS;
1437 }
1438
1439 /*
1440 * @unimplemented
1441 */
1442 NTSTATUS
1443 NTAPI
1444 KdChangeOption(IN KD_OPTION Option,
1445 IN ULONG InBufferBytes OPTIONAL,
1446 IN PVOID InBuffer,
1447 IN ULONG OutBufferBytes OPTIONAL,
1448 OUT PVOID OutBuffer,
1449 OUT PULONG OutBufferNeeded OPTIONAL)
1450 {
1451 /* HACK */
1452 return STATUS_SUCCESS;
1453 }
1454
1455 /*
1456 * @unimplemented
1457 */
1458 NTSTATUS
1459 NTAPI
1460 KdPowerTransition(IN DEVICE_POWER_STATE NewState)
1461 {
1462 /* HACK */
1463 return STATUS_SUCCESS;
1464 }
1465
1466 /*
1467 * @unimplemented
1468 */
1469 NTSTATUS
1470 NTAPI
1471 KdDisableDebugger(VOID)
1472 {
1473 /* HACK */
1474 return STATUS_SUCCESS;
1475 }
1476
1477 /*
1478 * @unimplemented
1479 */
1480 BOOLEAN
1481 NTAPI
1482 KdRefreshDebuggerNotPresent(VOID)
1483 {
1484 /* HACK */
1485 return KdDebuggerNotPresent;
1486 }
1487
1488 NTSTATUS
1489 NTAPI
1490 NtQueryDebugFilterState(ULONG ComponentId,
1491 ULONG Level)
1492 {
1493 /* HACK */
1494 return STATUS_SUCCESS;
1495 }
1496
1497 NTSTATUS
1498 NTAPI
1499 NtSetDebugFilterState(ULONG ComponentId,
1500 ULONG Level,
1501 BOOLEAN State)
1502 {
1503 /* HACK */
1504 return STATUS_SUCCESS;
1505 }
1506