00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
#include "kdp.h"
00032 
00033 
#if ACCASM && !defined(_MSC_VER)
00034 
long asm(
const char *,...);
00035 
#pragma intrinsic(asm)
00036 
#endif
00037 
00038 LARGE_INTEGER 
KdpQueryPerformanceCounter (
00039     IN PKTRAP_FRAME TrapFrame
00040     );
00041 
00042 extern LARGE_INTEGER 
Magic10000;
00043 #define SHIFT10000   13
00044 #define Convert100nsToMilliseconds(LARGE_INTEGER) (                         \
00045 
    RtlExtendedMagicDivide( (LARGE_INTEGER), Magic10000, SHIFT10000 )       \
00046 
    )
00047 
00048 
00049 
00050 
00051 
00052 
VOID
00053 
KdpProcessInternalBreakpoint (
00054     ULONG BreakpointNumber
00055     );
00056 
00057 
VOID
00058 
KdpGetVersion(
00059     IN PDBGKD_MANIPULATE_STATE64 m
00060     );
00061 
00062 
NTSTATUS
00063 
KdpNotSupported(
00064     IN PDBGKD_MANIPULATE_STATE64 m
00065     );
00066 
00067 
VOID
00068 
KdpCauseBugCheck(
00069     IN PDBGKD_MANIPULATE_STATE64 m
00070     );
00071 
00072 
NTSTATUS
00073 
KdpWriteBreakPointEx(
00074     IN PDBGKD_MANIPULATE_STATE64 m,
00075     IN PSTRING AdditionalData,
00076     IN PCONTEXT Context
00077     );
00078 
00079 
VOID
00080 
KdpRestoreBreakPointEx(
00081     IN PDBGKD_MANIPULATE_STATE64 m,
00082     IN PSTRING AdditionalData,
00083     IN PCONTEXT Context
00084     );
00085 
00086 
VOID
00087 
KdpSearchMemory(
00088     IN PDBGKD_MANIPULATE_STATE64 m,
00089     IN PSTRING AdditionalData,
00090     IN PCONTEXT Context
00091     );
00092 
00093 ULONG
00094 
KdpSearchHammingDistance (
00095     ULONG_PTR Left,
00096     ULONG_PTR Right
00097     );
00098 
00099 LOGICAL
00100 
KdpSearchPhysicalPage (
00101     IN PFN_NUMBER PageFrameIndex,
00102     ULONG_PTR RangeStart,
00103     ULONG_PTR RangeEnd,
00104     ULONG Flags
00105     );
00106 
00107 LOGICAL
00108 
KdpSearchPhysicalMemoryRequested (
00109     VOID
00110     );
00111 
00112 LOGICAL
00113 
KdpSearchPhysicalPageRange (
00114     VOID
00115     );
00116 
00117 
00118 
#if i386
00119 
VOID
00120 InternalBreakpointCheck (
00121     
PKDPC Dpc,
00122     PVOID DeferredContext,
00123     PVOID SystemArgument1,
00124     PVOID SystemArgument2
00125     );
00126 
00127 
VOID
00128 KdGetInternalBreakpoint(
00129     IN PDBGKD_MANIPULATE_STATE64 m
00130     );
00131 
00132 
long
00133 SymNumFor(
00134     ULONG_PTR pc
00135     );
00136 
00137 
void PotentialNewSymbol (ULONG_PTR pc);
00138 
00139 
void DumpTraceData(PSTRING MessageData);
00140 
00141 BOOLEAN
00142 TraceDataRecordCallInfo(
00143     ULONG InstructionsTraced,
00144     LONG CallLevelChange,
00145     ULONG_PTR pc
00146     );
00147 
00148 BOOLEAN
00149 SkippingWhichBP (
00150     PVOID thread,
00151     PULONG BPNum
00152     );
00153 
00154 BOOLEAN
00155 
KdpCheckTracePoint(
00156     IN PEXCEPTION_RECORD ExceptionRecord,
00157     IN OUT PCONTEXT ContextRecord
00158     );
00159 
00160 ULONG_PTR
00161 
KdpGetReturnAddress(
00162     IN PCONTEXT ContextRecord
00163     );
00164 
00165 ULONG_PTR
00166 
KdpGetCallNextOffset (
00167     ULONG_PTR Pc,
00168     IN PCONTEXT ContextRecord
00169     );
00170 
00171 LONG
00172 
KdpLevelChange (
00173     ULONG_PTR Pc,
00174     PCONTEXT ContextRecord,
00175     IN OUT PBOOLEAN SpecialCall
00176     );
00177 
00178 
#endif // i386
00179 
00180 
#ifdef ALLOC_PRAGMA
00181 
#pragma alloc_text(PAGEKD, KdEnterDebugger)
00182 
#pragma alloc_text(PAGEKD, KdExitDebugger)
00183 
#pragma alloc_text(PAGEKD, KdpTimeSlipDpcRoutine)
00184 
#pragma alloc_text(PAGEKD, KdpTimeSlipWork)
00185 
#pragma alloc_text(PAGEKD, KdpSendWaitContinue)
00186 
#pragma alloc_text(PAGEKD, KdpReadVirtualMemory)
00187 
00188 
#pragma alloc_text(PAGEKD, KdpWriteVirtualMemory)
00189 
00190 
#pragma alloc_text(PAGEKD, KdpGetContext)
00191 
#pragma alloc_text(PAGEKD, KdpSetContext)
00192 
#pragma alloc_text(PAGEKD, KdpWriteBreakpoint)
00193 
#pragma alloc_text(PAGEKD, KdpRestoreBreakpoint)
00194 
#pragma alloc_text(PAGEKD, KdpReportExceptionStateChange)
00195 
#pragma alloc_text(PAGEKD, KdpReportLoadSymbolsStateChange)
00196 
#pragma alloc_text(PAGEKD, KdpReadPhysicalMemory)
00197 
#pragma alloc_text(PAGEKD, KdpWritePhysicalMemory)
00198 
#pragma alloc_text(PAGEKD, KdpGetVersion)
00199 
#pragma alloc_text(PAGEKD, KdpNotSupported)
00200 
#pragma alloc_text(PAGEKD, KdpCauseBugCheck)
00201 
#pragma alloc_text(PAGEKD, KdpWriteBreakPointEx)
00202 
#pragma alloc_text(PAGEKD, KdpRestoreBreakPointEx)
00203 
#pragma alloc_text(PAGEKD, KdpSearchMemory)
00204 
#pragma alloc_text(PAGEKD, KdpSearchHammingDistance)
00205 
#pragma alloc_text(PAGEKD, KdpSearchPhysicalPage)
00206 
#pragma alloc_text(PAGEKD, KdpSearchPhysicalMemoryRequested)
00207 
#pragma alloc_text(PAGEKD, KdpSearchPhysicalPageRange)
00208 
#if DBG
00209 
#pragma alloc_text(PAGEKD, KdpDprintf)
00210 
#endif
00211 
#if i386
00212 
#pragma alloc_text(PAGEKD, InternalBreakpointCheck)
00213 
#pragma alloc_text(PAGEKD, KdSetInternalBreakpoint)
00214 
#pragma alloc_text(PAGEKD, KdGetTraceInformation)
00215 
#pragma alloc_text(PAGEKD, KdGetInternalBreakpoint)
00216 
#pragma alloc_text(PAGEKD, SymNumFor)
00217 
#pragma alloc_text(PAGEKD, PotentialNewSymbol)
00218 
#pragma alloc_text(PAGEKD, DumpTraceData)
00219 
#pragma alloc_text(PAGEKD, TraceDataRecordCallInfo)
00220 
#pragma alloc_text(PAGEKD, SkippingWhichBP)
00221 
#pragma alloc_text(PAGEKD, KdQuerySpecialCalls)
00222 
#pragma alloc_text(PAGEKD, KdSetSpecialCall)
00223 
#pragma alloc_text(PAGEKD, KdClearSpecialCalls)
00224 
#pragma alloc_text(PAGEKD, KdpCheckTracePoint)
00225 
#pragma alloc_text(PAGEKD, KdpProcessInternalBreakpoint)
00226 
#pragma alloc_text(PAGEKD, KdpCheckLowMemory)
00227 
#endif // i386
00228 
#endif // ALLOC_PRAGMA
00229 
00230 
00231 
00232 
00233 
00234 LONG 
KdDisableCount = 0 ;
00235 BOOLEAN 
KdPreviouslyEnabled ;
00236 
00237 
00238 
#if DBG
00239 
VOID
00240 KdpDprintf(
00241     IN PCHAR f,
00242     ...
00243     )
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260 {
00261     
char    buf[100];
00262     STRING  Output;
00263     va_list mark;
00264 
00265     va_start(mark, f);
00266     _vsnprintf(buf, 100, f, mark);
00267     va_end(mark);
00268 
00269     Output.Buffer = buf;
00270     Output.Length = 
strlen(Output.Buffer);
00271     
KdpPrintString(&Output);
00272 }
00273 
#endif // DBG
00274 
00275 
00276 BOOLEAN
00277 KdEnterDebugger(
00278     IN PKTRAP_FRAME TrapFrame,
00279     IN PKEXCEPTION_FRAME ExceptionFrame
00280     )
00281 
00282 
00283 
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294 
00295 
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303 
00304 {
00305 
00306     BOOLEAN Enable;
00307     TIME_FIELDS 
TimeFields;
00308 
#if DBG
00309 
    extern ULONG 
KiFreezeFlag;
00310 
#endif
00311 
00312     
00313     
00314     
00315     
00316 
00317     
if (TrapFrame) {
00318         
KdTimerStop = 
KdpQueryPerformanceCounter (TrapFrame);
00319         
KdTimerDifference.QuadPart = 
KdTimerStop.QuadPart - 
KdTimerStart.QuadPart;
00320     } 
else {
00321         
KdTimerStop.QuadPart = 0;
00322     }
00323 
00324     
00325     
00326     
00327     
00328     
00329 
00330     Enable = 
KeFreezeExecution(TrapFrame, ExceptionFrame);
00331     
KdpPortLocked = 
KiTryToAcquireSpinLock(&
KdpDebuggerLock);
00332     
KdPortSave();
00333     
KdEnteredDebugger = 
TRUE;
00334 
00335 
#if DBG
00336 
00337     
if ((
KiFreezeFlag & 
FREEZE_BACKUP) != 0) {
00338         
DPRINT((
"FreezeLock was jammed!  Backup SpinLock was used!\n"));
00339     }
00340 
00341     
if ((
KiFreezeFlag & 
FREEZE_SKIPPED_PROCESSOR) != 0) {
00342         
DPRINT((
"Some processors not frozen in debugger!\n"));
00343     }
00344 
00345     
if (
KdpPortLocked == 
FALSE) {
00346         
DPRINT((
"Port lock was not acquired!\n"));
00347     }
00348 
00349 
#endif
00350 
00351     
return Enable;
00352 }
00353 
00354 
VOID
00355 KdExitDebugger(
00356     IN BOOLEAN Enable
00357     )
00358 
00359 
00360 
00361 
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369 
00370 
00371 
00372 
00373 
00374 
00375 
00376 {
00377     ULONG ElapsedTime;
00378     ULARGE_INTEGER TimeDifference;
00379     TIME_FIELDS 
TimeFields;
00380     ULONG Pending;
00381 
00382     
00383     
00384     
00385 
00386     
KdPortRestore();
00387     
if (
KdpPortLocked) {
00388         
KdpPortUnlock();
00389     }
00390 
00391     
KeThawExecution(Enable);
00392 
00393     
00394     
00395     
00396     
00397 
00398     
if (
KdTimerStop.QuadPart == 0) {
00399         
KdTimerStart = 
KdTimerStop;
00400     } 
else {
00401         
KdTimerStart = 
KeQueryPerformanceCounter(
NULL);
00402     }
00403 
00404     
00405     
00406     
00407 
00408     
if (!
PoHiberInProgress) {
00409 
00410         Pending = InterlockedIncrement(&
KdpTimeSlipPending);
00411 
00412         
00413         
00414         
00415 
00416         
if (Pending == 1) {
00417             InterlockedIncrement(&
KdpTimeSlipPending);
00418             
KeInsertQueueDpc(&
KdpTimeSlipDpc, 
NULL, 
NULL);
00419         }
00420     }
00421 
00422     
return;
00423 }
00424 
00425 
00426 
VOID
00427 KdUpdateTimeSlipEvent(
00428     PVOID Event
00429     )
00430 
00431 
00432 
00433 
00434 
00435 
00436 
00437 
00438 
00439 
00440 
00441 
00442 
00443 
00444 
00445 
00446 
00447 
00448 {
00449     KIRQL OldIrql;
00450 
00451     
KeAcquireSpinLock(&
KdpTimeSlipEventLock, &OldIrql);
00452 
00453     
00454     
00455     
00456     
00457 
00458     
if (
KdpTimeSlipEvent != 
NULL) {
00459         
ObDereferenceObject(
KdpTimeSlipEvent);
00460     }
00461 
00462     
KdpTimeSlipEvent = 
Event;
00463 
00464     
KeReleaseSpinLock(&
KdpTimeSlipEventLock, OldIrql);
00465 }
00466 
00467 
VOID
00468 KdpTimeSlipDpcRoutine (
00469     
PKDPC Dpc,
00470     PVOID DeferredContext,
00471     PVOID SystemArgument1,
00472     PVOID SystemArgument2
00473     )
00474 {
00475     LONG OldCount, NewCount, j;
00476 
00477     
00478     
00479     
00480     
00481     
00482 
00483     j = 
KdpTimeSlipPending;
00484     
do {
00485         OldCount = j;
00486         NewCount = OldCount > 1 ? 1 : 0;
00487 
00488         j = InterlockedCompareExchange(&
KdpTimeSlipPending, NewCount, OldCount);
00489 
00490     } 
while (j != OldCount);
00491 
00492     
00493     
00494     
00495 
00496     
if (NewCount) {
00497         
ExQueueWorkItem(&
KdpTimeSlipWorkItem, 
DelayedWorkQueue);
00498     }
00499 }
00500 
00501 
VOID
00502 KdpTimeSlipWork (
00503     IN PVOID Context
00504     )
00505 {
00506     KIRQL               OldIrql;
00507     LARGE_INTEGER       DueTime;
00508 
00509     
00510     
00511     
00512 
00513     
ExAcquireTimeRefreshLock();
00514     
ExUpdateSystemTimeFromCmos (
FALSE, 0);
00515     
ExReleaseTimeRefreshLock();
00516 
00517     
00518     
00519     
00520 
00521     
KeAcquireSpinLock(&
KdpTimeSlipEventLock, &OldIrql);
00522     
if (
KdpTimeSlipEvent) {
00523         
KeSetEvent (
KdpTimeSlipEvent, 0, 
FALSE);
00524     }
00525     
KeReleaseSpinLock(&
KdpTimeSlipEventLock, OldIrql);
00526 
00527     
00528     
00529     
00530 
00531     DueTime.QuadPart = -1800000000;
00532     
KeSetTimer (&
KdpTimeSlipTimer, DueTime, &
KdpTimeSlipDpc);
00533 }
00534 
00535 
#if i386
00536 
VOID
00537 InternalBreakpointCheck (
00538     
PKDPC Dpc,
00539     PVOID DeferredContext,
00540     PVOID SystemArgument1,
00541     PVOID SystemArgument2
00542     )
00543 {
00544     LARGE_INTEGER dueTime;
00545     ULONG i;
00546 
00547     UNREFERENCED_PARAMETER(Dpc);
00548     UNREFERENCED_PARAMETER(DeferredContext);
00549     UNREFERENCED_PARAMETER(SystemArgument1);
00550     UNREFERENCED_PARAMETER(SystemArgument2);
00551 
00552     dueTime.LowPart = (ULONG)(-1 * 10 * 1000 * 1000);
00553     dueTime.HighPart = -1;
00554 
00555     
KeSetTimer(
00556         &InternalBreakpointTimer,
00557         dueTime,
00558         &InternalBreakpointCheckDpc
00559         );
00560 
00561     
for ( i = 0 ; i < 
KdpNumInternalBreakpoints; i++ ) {
00562         
if ( !(
KdpInternalBPs[i].
Flags & DBGKD_INTERNAL_BP_FLAG_INVALID) &&
00563              (
KdpInternalBPs[i].
Flags & DBGKD_INTERNAL_BP_FLAG_COUNTONLY) ) {
00564 
00565             
PDBGKD_INTERNAL_BREAKPOINT b = 
KdpInternalBPs + i;
00566             ULONG callsThisPeriod;
00567 
00568             callsThisPeriod = b->
Calls - b->CallsLastCheck;
00569             
if ( callsThisPeriod > b->MaxCallsPerPeriod ) {
00570                 b->MaxCallsPerPeriod = callsThisPeriod;
00571             }
00572             b->CallsLastCheck = b->Calls;
00573         }
00574     }
00575 
00576     
return;
00577 
00578 } 
00579 
00580 
00581 
VOID
00582 KdSetInternalBreakpoint (
00583     IN PDBGKD_MANIPULATE_STATE64 m
00584     )
00585 
00586 
00587 
00588 
00589 
00590 
00591 
00592 
00593 
00594 
00595 
00596 
00597 
00598 
00599 
00600 
00601 
00602 
00603 {
00604     ULONG i;
00605     
PDBGKD_INTERNAL_BREAKPOINT bp = 
NULL;
00606     ULONG savedFlags;
00607 
00608     
for ( i = 0 ; i < 
KdpNumInternalBreakpoints; i++ ) {
00609         
if ( 
KdpInternalBPs[i].
Addr ==
00610                             m->u.SetInternalBreakpoint.BreakpointAddress ) {
00611             bp = &
KdpInternalBPs[i];
00612             
break;
00613         }
00614     }
00615 
00616     
if ( !bp ) {
00617         
for ( i = 0; i < 
KdpNumInternalBreakpoints; i++ ) {
00618             
if ( 
KdpInternalBPs[i].
Flags & DBGKD_INTERNAL_BP_FLAG_INVALID ) {
00619                 bp = &
KdpInternalBPs[i];
00620                 
break;
00621             }
00622         }
00623     }
00624 
00625     
if ( !bp ) {
00626         
if ( 
KdpNumInternalBreakpoints >= 
DBGKD_MAX_INTERNAL_BREAKPOINTS ) {
00627             
return; 
00628         }
00629         bp = &
KdpInternalBPs[
KdpNumInternalBreakpoints++];
00630         bp->
Flags |= DBGKD_INTERNAL_BP_FLAG_INVALID; 
00631     }
00632 
00633     
if ( bp->Flags & DBGKD_INTERNAL_BP_FLAG_INVALID ) {
00634         
if ( m->u.SetInternalBreakpoint.Flags &
00635                                         DBGKD_INTERNAL_BP_FLAG_INVALID ) {
00636             
return; 
00637         }
00638         bp->Calls = bp->MaxInstructions = bp->TotalInstructions = 0;
00639         bp->CallsLastCheck = bp->MaxCallsPerPeriod = 0;
00640         bp->MinInstructions = 0xffffffff;
00641         bp->Handle = 0;
00642         bp->Thread = 0;
00643     }
00644 
00645     savedFlags = bp->Flags;
00646     bp->Flags = m->u.SetInternalBreakpoint.Flags; 
00647     bp->Addr = m->u.SetInternalBreakpoint.BreakpointAddress;
00648 
00649     
if ( bp->Flags & (DBGKD_INTERNAL_BP_FLAG_INVALID |
00650                       DBGKD_INTERNAL_BP_FLAG_SUSPENDED) ) {
00651 
00652         
if ( (bp->Flags & DBGKD_INTERNAL_BP_FLAG_INVALID) &&
00653              (bp->Thread != 0) ) {
00654             
00655             bp->Flags &= ~DBGKD_INTERNAL_BP_FLAG_INVALID;
00656             bp->Flags |= DBGKD_INTERNAL_BP_FLAG_DYING;
00657         }
00658 
00659         
00660 
00661         
if ( bp->Handle != 0 ) {
00662             
KdpDeleteBreakpoint( bp->Handle );
00663         }
00664         bp->Handle = 0;
00665 
00666         
return;
00667     }
00668 
00669     
00670 
00671     
if ( savedFlags & (DBGKD_INTERNAL_BP_FLAG_INVALID |
00672                        DBGKD_INTERNAL_BP_FLAG_SUSPENDED) ) {
00673         
00674         bp->Handle = 
KdpAddBreakpoint( (PVOID)bp->Addr );
00675     }
00676 
00677     
if ( 
BreakpointsSuspended ) {
00678         
KdpSuspendBreakpoint( bp->Handle );
00679     }
00680 
00681 } 
00682 
00683 
NTSTATUS
00684 KdGetTraceInformation(
00685     PVOID SystemInformation,
00686     ULONG SystemInformationLength,
00687     PULONG ReturnLength
00688     )
00689 
00690 
00691 
00692 
00693 
00694 
00695 
00696 
00697 
00698 
00699 
00700 
00701 
00702 
00703 
00704 
00705 
00706 
00707 
00708 
00709 
00710 
00711 
00712 {
00713     ULONG numEntries = 0;
00714     ULONG i = 0;
00715     PDBGKD_GET_INTERNAL_BREAKPOINT64 outPtr;
00716 
00717     
for ( i = 0; i < 
KdpNumInternalBreakpoints; i++ ) {
00718         
if ( !(
KdpInternalBPs[i].
Flags & DBGKD_INTERNAL_BP_FLAG_INVALID) ) {
00719             numEntries++;
00720         }
00721     }
00722 
00723     *ReturnLength = numEntries * 
sizeof(DBGKD_GET_INTERNAL_BREAKPOINT64);
00724     
if ( *ReturnLength > SystemInformationLength ) {
00725         
return STATUS_INFO_LENGTH_MISMATCH;
00726     }
00727 
00728     
00729     
00730     
00731 
00732     outPtr = (PDBGKD_GET_INTERNAL_BREAKPOINT64)SystemInformation;
00733     
for ( i = 0; i < 
KdpNumInternalBreakpoints; i++ ) {
00734         
if ( !(
KdpInternalBPs[i].
Flags & DBGKD_INTERNAL_BP_FLAG_INVALID) ) {
00735             outPtr->BreakpointAddress = 
KdpInternalBPs[i].
Addr;
00736             outPtr->Flags = 
KdpInternalBPs[i].
Flags;
00737             outPtr->Calls = 
KdpInternalBPs[i].
Calls;
00738             outPtr->MaxCallsPerPeriod = 
KdpInternalBPs[i].
MaxCallsPerPeriod;
00739             outPtr->MinInstructions = 
KdpInternalBPs[i].
MinInstructions;
00740             outPtr->MaxInstructions = 
KdpInternalBPs[i].
MaxInstructions;
00741             outPtr->TotalInstructions = 
KdpInternalBPs[i].
TotalInstructions;
00742             outPtr++;
00743         }
00744     }
00745 
00746     
return STATUS_SUCCESS;
00747 
00748 } 
00749 
00750 
VOID
00751 KdGetInternalBreakpoint(
00752     IN PDBGKD_MANIPULATE_STATE64 m
00753     )
00754 
00755 
00756 
00757 
00758 
00759 
00760 
00761 
00762 
00763 
00764 
00765 
00766 
00767 
00768 
00769 
00770 
00771 
00772 {
00773     ULONG i;
00774     
PDBGKD_INTERNAL_BREAKPOINT bp = 
NULL;
00775     STRING messageHeader;
00776 
00777     messageHeader.Length = 
sizeof(*m);
00778     messageHeader.Buffer = (PCHAR)m;
00779 
00780     
for ( i = 0; i < 
KdpNumInternalBreakpoints; i++ ) {
00781         
if ( !(
KdpInternalBPs[i].
Flags & (DBGKD_INTERNAL_BP_FLAG_INVALID |
00782                                           DBGKD_INTERNAL_BP_FLAG_SUSPENDED)) &&
00783              (
KdpInternalBPs[i].
Addr ==
00784                         m->u.GetInternalBreakpoint.BreakpointAddress) ) {
00785             bp = &
KdpInternalBPs[i];
00786             
break;
00787         }
00788     }
00789 
00790     
if ( !bp ) {
00791         m->u.GetInternalBreakpoint.
Flags = DBGKD_INTERNAL_BP_FLAG_INVALID;
00792         m->u.GetInternalBreakpoint.Calls = 0;
00793         m->u.GetInternalBreakpoint.MaxCallsPerPeriod = 0;
00794         m->u.GetInternalBreakpoint.MinInstructions = 0;
00795         m->u.GetInternalBreakpoint.MaxInstructions = 0;
00796         m->u.GetInternalBreakpoint.TotalInstructions = 0;
00797         m->ReturnStatus = STATUS_UNSUCCESSFUL;
00798     } 
else {
00799         m->u.GetInternalBreakpoint.Flags = bp->Flags;
00800         m->u.GetInternalBreakpoint.Calls = bp->Calls;
00801         m->u.GetInternalBreakpoint.MaxCallsPerPeriod = bp->MaxCallsPerPeriod;
00802         m->u.GetInternalBreakpoint.MinInstructions = bp->MinInstructions;
00803         m->u.GetInternalBreakpoint.MaxInstructions = bp->MaxInstructions;
00804         m->u.GetInternalBreakpoint.TotalInstructions = bp->TotalInstructions;
00805         m->ReturnStatus = STATUS_SUCCESS;
00806     }
00807 
00808     m->ApiNumber = DbgKdGetInternalBreakPointApi;
00809 
00810     
KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
00811                     &messageHeader,
00812                     NULL
00813                     );
00814 
00815     
return;
00816 
00817 } 
00818 
#endif // i386
00819 
00820 
KCONTINUE_STATUS
00821 KdpSendWaitContinue (
00822     IN ULONG OutPacketType,
00823     IN PSTRING OutMessageHeader,
00824     IN PSTRING OutMessageData OPTIONAL,
00825     IN OUT PCONTEXT ContextRecord
00826     )
00827 
00828 
00829 
00830 
00831 
00832 
00833 
00834 
00835 
00836 
00837 
00838 
00839 
00840 
00841 
00842 
00843 
00844 
00845 
00846 
00847 
00848 
00849 
00850 
00851 
00852 
00853 
00854 
00855 
00856 
00857 
00858 
00859 {
00860 
00861     ULONG Length;
00862     STRING MessageData;
00863     STRING MessageHeader;
00864     DBGKD_MANIPULATE_STATE64 ManipulateState;
00865     ULONG ReturnCode;
00866     
NTSTATUS Status;
00867     
KCONTINUE_STATUS ContinueStatus;
00868 
00869     
00870     
00871     
00872     
00873 
00874     MessageHeader.MaximumLength = 
sizeof(DBGKD_MANIPULATE_STATE64);
00875     MessageHeader.Buffer = (PCHAR)&ManipulateState;
00876     MessageData.MaximumLength = 
KDP_MESSAGE_BUFFER_SIZE;
00877     MessageData.Buffer = (PCHAR)
KdpMessageBuffer;
00878 
00879 ResendPacket:
00880 
00881     
00882     
00883     
00884     
00885 
00886     
KdpSendPacket(
00887                   OutPacketType,
00888                   OutMessageHeader,
00889                   OutMessageData
00890                   );
00891 
00892     
00893     
00894     
00895     
00896     
00897     
00898 
00899     
if (
KdDebuggerNotPresent) {
00900         
return ContinueSuccess;
00901     }
00902 
00903     
while (
TRUE) {
00904 
00905         
00906         
00907         
00908 
00909         
do {
00910 
00911             ReturnCode = 
KdpReceivePacket(
00912                             PACKET_TYPE_KD_STATE_MANIPULATE,
00913                             &MessageHeader,
00914                             &MessageData,
00915                             &Length
00916                             );
00917             
if (ReturnCode == (
USHORT)
KDP_PACKET_RESEND) {
00918                 
goto ResendPacket;
00919             }
00920         } 
while (ReturnCode == 
KDP_PACKET_TIMEOUT);
00921 
00922         
00923         
00924         
00925 
00926         
switch (ManipulateState.ApiNumber) {
00927 
00928         
case DbgKdReadVirtualMemoryApi:
00929             
KdpReadVirtualMemory(&ManipulateState,&MessageData,ContextRecord);
00930             
break;
00931 
#if 0
00932 
        case DbgKdReadVirtualMemory64Api:
00933             
KdpReadVirtualMemory64(&ManipulateState,&MessageData,ContextRecord);
00934             
break;
00935 
#endif
00936 
        case DbgKdWriteVirtualMemoryApi:
00937             
KdpWriteVirtualMemory(&ManipulateState,&MessageData,ContextRecord);
00938             
break;
00939 
#if 0
00940 
        case DbgKdWriteVirtualMemory64Api:
00941             
KdpWriteVirtualMemory64(&ManipulateState,&MessageData,ContextRecord);
00942             
break;
00943 
#endif
00944 
00945         
case DbgKdCheckLowMemoryApi:
00946             
KdpCheckLowMemory (&ManipulateState);
00947             
break;
00948 
00949         
case DbgKdReadPhysicalMemoryApi:
00950             
KdpReadPhysicalMemory(&ManipulateState,&MessageData,ContextRecord);
00951             
break;
00952 
00953         
case DbgKdWritePhysicalMemoryApi:
00954             
KdpWritePhysicalMemory(&ManipulateState,&MessageData,ContextRecord);
00955             
break;
00956 
00957         
case DbgKdGetContextApi:
00958             
KdpGetContext(&ManipulateState,&MessageData,ContextRecord);
00959             
break;
00960 
00961         
case DbgKdSetContextApi:
00962             
KdpSetContext(&ManipulateState,&MessageData,ContextRecord);
00963             
break;
00964 
00965         
case DbgKdWriteBreakPointApi:
00966             
KdpWriteBreakpoint(&ManipulateState,&MessageData,ContextRecord);
00967             
break;
00968 
00969         
case DbgKdRestoreBreakPointApi:
00970             
KdpRestoreBreakpoint(&ManipulateState,&MessageData,ContextRecord);
00971             
break;
00972 
00973         
case DbgKdReadControlSpaceApi:
00974             
KdpReadControlSpace(&ManipulateState,&MessageData,ContextRecord);
00975             
break;
00976 
00977         
case DbgKdWriteControlSpaceApi:
00978             
KdpWriteControlSpace(&ManipulateState,&MessageData,ContextRecord);
00979             
break;
00980 
00981         
case DbgKdReadIoSpaceApi:
00982             
KdpReadIoSpace(&ManipulateState,&MessageData,ContextRecord);
00983             
break;
00984 
00985         
case DbgKdWriteIoSpaceApi:
00986             
KdpWriteIoSpace(&ManipulateState,&MessageData,ContextRecord);
00987             
break;
00988 
00989 
#ifdef _ALPHA_
00990 
00991         
case DbgKdReadIoSpaceExtendedApi:
00992             
KdpReadIoSpaceExtended(&ManipulateState,&MessageData,ContextRecord);
00993             
break;
00994 
00995         
case DbgKdWriteIoSpaceExtendedApi:
00996             
KdpWriteIoSpaceExtended(&ManipulateState,&MessageData,ContextRecord);
00997             
break;
00998 
00999         
case DbgKdGetBusDataApi:
01000             
KdpGetBusData(&ManipulateState,&MessageData,ContextRecord);
01001             
break;
01002 
01003         
case DbgKdSetBusDataApi:
01004             
KdpSetBusData(&ManipulateState,&MessageData,ContextRecord);
01005             
break;
01006 
01007 
#endif // _ALPHA_
01008 
01009         
case DbgKdContinueApi:
01010             
if (
NT_SUCCESS(ManipulateState.u.Continue.ContinueStatus) != 
FALSE) {
01011                 
return ContinueSuccess;
01012             } 
else {
01013                 
return ContinueError;
01014             }
01015             
break;
01016 
01017         
case DbgKdContinueApi2:
01018             
if (
NT_SUCCESS(ManipulateState.u.Continue2.ContinueStatus) != 
FALSE) {
01019                 
KdpGetStateChange(&ManipulateState,ContextRecord);
01020                 
return ContinueSuccess;
01021             } 
else {
01022                 
return ContinueError;
01023             }
01024             
break;
01025 
01026         
case DbgKdRebootApi:
01027             
KdpReboot();
01028             
break;
01029 
01030 
#if i386
01031 
        case DbgKdReadMachineSpecificRegister:
01032             
KdpReadMachineSpecificRegister(&ManipulateState,&MessageData,ContextRecord);
01033             
break;
01034 
01035         
case DbgKdWriteMachineSpecificRegister:
01036             
KdpWriteMachineSpecificRegister(&ManipulateState,&MessageData,ContextRecord);
01037             
break;
01038 
01039         
case DbgKdSetSpecialCallApi:
01040             
KdSetSpecialCall(&ManipulateState,ContextRecord);
01041             
break;
01042 
01043         
case DbgKdClearSpecialCallsApi:
01044             
KdClearSpecialCalls();
01045             
break;
01046 
01047         
case DbgKdSetInternalBreakPointApi:
01048             KdSetInternalBreakpoint(&ManipulateState);
01049             
break;
01050 
01051         
case DbgKdGetInternalBreakPointApi:
01052             KdGetInternalBreakpoint(&ManipulateState);
01053             
break;
01054 
#endif
01055 
01056         
case DbgKdGetVersionApi:
01057             
KdpGetVersion(&ManipulateState);
01058             
break;
01059 
01060         
case DbgKdCauseBugCheckApi:
01061             
KdpCauseBugCheck(&ManipulateState);
01062             
break;
01063 
01064         
case DbgKdPageInApi:
01065             
KdpNotSupported(&ManipulateState);
01066             
break;
01067 
01068         
case DbgKdWriteBreakPointExApi:
01069             
Status = 
KdpWriteBreakPointEx(&ManipulateState,
01070                                           &MessageData,
01071                                           ContextRecord);
01072             
if (
Status) {
01073                 ManipulateState.ApiNumber = DbgKdContinueApi;
01074                 ManipulateState.u.Continue.ContinueStatus = 
Status;
01075                 
return ContinueError;
01076             }
01077             
break;
01078 
01079         
case DbgKdRestoreBreakPointExApi:
01080             
KdpRestoreBreakPointEx(&ManipulateState,&MessageData,ContextRecord);
01081             
break;
01082 
01083         
case DbgKdSwitchProcessor:
01084             
KdPortRestore ();
01085             ContinueStatus = 
KeSwitchFrozenProcessor(ManipulateState.Processor);
01086             
KdPortSave ();
01087             
return ContinueStatus;
01088 
01089         
case DbgKdSearchMemoryApi:
01090             
KdpSearchMemory(&ManipulateState, &MessageData, ContextRecord);
01091             
break;
01092 
01093             
01094             
01095             
01096 
01097         
default:
01098             MessageData.Length = 0;
01099             ManipulateState.ReturnStatus = STATUS_UNSUCCESSFUL;
01100             
KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &MessageHeader, &MessageData);
01101             
break;
01102         }
01103 
01104 
#ifdef _ALPHA_
01105 
01106         
01107         
01108         
01109         
01110         
01111         
01112         
01113 
01114 
#if defined(_MSC_VER)
01115 
        __PAL_IMB();
01116 
#else
01117 
        asm( 
"call_pal 0x86" );   
01118 
#endif
01119 
01120 
#endif
01121 
01122     }
01123 }
01124 
01125 
VOID
01126 KdpReadVirtualMemory(
01127     IN PDBGKD_MANIPULATE_STATE64 m,
01128     IN PSTRING AdditionalData,
01129     IN PCONTEXT Context
01130     )
01131 
01132 
01133 
01134 
01135 
01136 
01137 
01138 
01139 
01140 
01141 
01142 
01143 
01144 
01145 
01146 
01147 
01148 
01149 
01150 
01151 
01152 
01153 
01154 {
01155     ULONG Length;
01156     STRING MessageHeader;
01157 
#if defined(_ALPHA_) && !defined(_AXP64_)
01158 
    UCHAR * POINTER_64 Address;
01159     PUCHAR Destination;
01160     UCHAR * POINTER_64 Source;
01161     PUCHAR Source32;
01162 
#endif
01163 
01164     
01165     
01166     
01167 
01168     Length = m->u.ReadMemory.TransferCount;
01169     
if (Length > (PACKET_MAX_SIZE - 
sizeof(DBGKD_MANIPULATE_STATE64))) {
01170         Length = PACKET_MAX_SIZE - 
sizeof(DBGKD_MANIPULATE_STATE64);
01171     }
01172 
01173     
01174     
01175     
01176 
01177 
#if defined(_ALPHA_) && !defined(_AXP64_)
01178 
01179     AdditionalData->Length = (
USHORT)Length;
01180 
01181     Destination = AdditionalData->Buffer;
01182     Source = (UCHAR * POINTER_64)m->u.ReadMemory.TargetBaseAddress;
01183     Source32 = (PUCHAR)m->u.ReadMemory.TargetBaseAddress;
01184     
while (Length > 0) {
01185         
if ((LONGLONG)Source != (LONGLONG)((LONG)Source)) {
01186             
if ((Address = 
MmDbgReadCheck64(Source)) == NULL64) {
01187                 
break;
01188             }
01189         } 
else {
01190             
if ((Address = 
MmDbgReadCheck(Source32)) == NULL64) {
01191                 
break;
01192             }
01193         }
01194 
01195         *Destination++ = *Address;
01196         Source   += 1;
01197         Source32 += 1;
01198         Length -= 1;
01199     }
01200 
01201     
01202     
01203     
01204     
01205 
01206     m->ReturnStatus = STATUS_SUCCESS;
01207     
if (Length != 0) {
01208         m->ReturnStatus = STATUS_UNSUCCESSFUL;
01209     }
01210 
01211     
01212     
01213     
01214     
01215 
01216     m->u.ReadMemory.ActualBytesRead = AdditionalData->Length - Length;
01217 
#else
01218 
    AdditionalData->Length = (
USHORT)
KdpMoveMemory(AdditionalData->Buffer,
01219                                                    (PVOID)m->u.ReadMemory.TargetBaseAddress,
01220                                                    Length);
01221 
01222     
01223     
01224     
01225     
01226 
01227     m->ReturnStatus = STATUS_SUCCESS;
01228     
if (Length != AdditionalData->Length) {
01229         m->ReturnStatus = STATUS_UNSUCCESSFUL;
01230     }
01231 
01232     
01233     
01234     
01235     
01236 
01237     m->u.ReadMemory.ActualBytesRead = AdditionalData->Length;
01238 
#endif
01239 
01240     MessageHeader.Length = 
sizeof(DBGKD_MANIPULATE_STATE64);
01241     MessageHeader.Buffer = (PCHAR)m;
01242     
KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
01243                   &MessageHeader,
01244                   AdditionalData);
01245 
01246     
return;
01247 }
01248 
01249 
#if 0
01250 
VOID
01251 
KdpReadVirtualMemory64(
01252     IN PDBGKD_MANIPULATE_STATE64 m,
01253     IN PSTRING AdditionalData,
01254     IN PCONTEXT Context
01255     )
01256 
01257 
01258 
01259 
01260 
01261 
01262 
01263 
01264 
01265 
01266 
01267 
01268 
01269 
01270 
01271 
01272 
01273 
01274 
01275 
01276 
01277 
01278 
01279 {
01280 
01281     UCHAR * POINTER_64 Address;
01282     PUCHAR Destination;
01283     ULONG Length;
01284     STRING MessageHeader;
01285     UCHAR * POINTER_64 Source;
01286 
01287     
01288     
01289     
01290 
01291     Length = m->u.ReadMemory64.TransferCount;
01292     
if (Length > (PACKET_MAX_SIZE - 
sizeof(DBGKD_MANIPULATE_STATE64))) {
01293         Length = PACKET_MAX_SIZE - 
sizeof(DBGKD_MANIPULATE_STATE64);
01294     }
01295 
01296     
01297     
01298     
01299 
01300     AdditionalData->Length = (
USHORT)Length;
01301 
01302 
#if defined(_MIPS_) || defined(_ALPHA_)
01303 
01304     Destination = AdditionalData->Buffer;
01305     Source = (UCHAR * POINTER_64)m->u.ReadMemory64.TargetBaseAddress;
01306     
while (Length > 0) {
01307         
if ((Address = 
MmDbgReadCheck64(Source)) == NULL64) {
01308             
break;
01309         }
01310 
01311         *Destination++ = *Address;
01312         Source += 1;
01313         Length -= 1;
01314     }
01315 
01316 
#endif
01317 
01318     
01319     
01320     
01321     
01322 
01323     m->ReturnStatus = STATUS_SUCCESS;
01324     
if (Length != 0) {
01325         m->ReturnStatus = STATUS_UNSUCCESSFUL;
01326     }
01327 
01328     
01329     
01330     
01331     
01332 
01333     m->u.ReadMemory64.ActualBytesRead = AdditionalData->Length - Length;
01334     MessageHeader.Length = 
sizeof(DBGKD_MANIPULATE_STATE64);
01335     MessageHeader.Buffer = (PCHAR)m;
01336     
KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
01337                   &MessageHeader,
01338                   AdditionalData);
01339 
01340     
return;
01341 }
01342 
#endif
01343 
01344 
VOID
01345 KdpWriteVirtualMemory(
01346     IN PDBGKD_MANIPULATE_STATE64 m,
01347     IN PSTRING AdditionalData,
01348     IN PCONTEXT Context
01349     )
01350 
01351 
01352 
01353 
01354 
01355 
01356 
01357 
01358 
01359 
01360 
01361 
01362 
01363 
01364 
01365 
01366 
01367 
01368 
01369 
01370 
01371 
01372 
01373 {
01374 
01375     ULONG Length;
01376     STRING MessageHeader;
01377     HARDWARE_PTE Opaque;
01378 
01379 
#if defined(_ALPHA_) && !defined(_AXP64_)
01380 
    UCHAR * POINTER_64 Address;
01381     UCHAR * POINTER_64 Destination;
01382     PUCHAR Address32;
01383     PUCHAR Source;
01384     PUCHAR Destination32;
01385 
01386 
01387     
01388     
01389     
01390 
01391     Length = AdditionalData->Length;
01392 
01393     Destination = (UCHAR * POINTER_64)m->u.WriteMemory.TargetBaseAddress;
01394     Destination32 = (PUCHAR)m->u.WriteMemory.TargetBaseAddress;
01395     Source = AdditionalData->Buffer;
01396     
while (Length > 0) {
01397         Address=Destination;
01398         Address32 = 
NULL;
01399         
if ((LONGLONG)Destination != (LONGLONG)((LONG)Destination)) {
01400             
if ((Address = 
MmDbgWriteCheck64(Destination)) == NULL64) {
01401                 
break;
01402             }
01403         } 
else {
01404             
if ((Address32 = 
MmDbgWriteCheck(Destination32, &Opaque)) == 
NULL) {
01405                 
break;
01406             }
01407         }
01408 
01409         
if (Address32 != 
NULL) {
01410             *Address32 = *Source++;
01411             
MmDbgReleaseAddress(Address32, &Opaque);
01412         }
01413         
else {
01414             *Address = *Source++;
01415         }
01416         Destination   += 1;
01417         Destination32 += 1;
01418         Length -= 1;
01419     }
01420 
01421     
01422     
01423     
01424     
01425 
01426     m->ReturnStatus = STATUS_SUCCESS;
01427     
if (Length != 0) {
01428         m->ReturnStatus = STATUS_UNSUCCESSFUL;
01429     }
01430 
01431     
01432     
01433     
01434     
01435 
01436     m->u.WriteMemory.ActualBytesWritten = AdditionalData->Length - Length;
01437     MessageHeader.Length = 
sizeof(DBGKD_MANIPULATE_STATE64);
01438     MessageHeader.Buffer = (PCHAR)m;
01439     
KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
01440                   &MessageHeader,
01441                   
NULL);
01442 
01443     
return;
01444 
#else
01445 
01446     
01447     
01448     
01449 
01450     Length = 
KdpMoveMemory((PVOID)m->u.WriteMemory.TargetBaseAddress,
01451                            AdditionalData->Buffer,
01452                            AdditionalData->Length);
01453 
01454     
01455     
01456     
01457     
01458 
01459     m->ReturnStatus = STATUS_SUCCESS;
01460     
if (Length != AdditionalData->Length) {
01461         m->ReturnStatus = STATUS_UNSUCCESSFUL;
01462     }
01463 
01464     
01465     
01466     
01467     
01468 
01469     m->u.WriteMemory.ActualBytesWritten = Length;
01470     MessageHeader.Length = 
sizeof(DBGKD_MANIPULATE_STATE64);
01471     MessageHeader.Buffer = (PCHAR)m;
01472     
KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
01473                   &MessageHeader,
01474                   
NULL);
01475 
01476     
return;
01477 
#endif
01478 
}
01479 
01480 
#if 0
01481 
VOID
01482 
KdpWriteVirtualMemory64(
01483     IN PDBGKD_MANIPULATE_STATE64 m,
01484     IN PSTRING AdditionalData,
01485     IN PCONTEXT Context
01486     )
01487 
01488 
01489 
01490 
01491 
01492 
01493 
01494 
01495 
01496 
01497 
01498 
01499 
01500 
01501 
01502 
01503 
01504 
01505 
01506 
01507 
01508 
01509 
01510 {
01511 
01512     UCHAR * POINTER_64 Address;
01513     UCHAR * POINTER_64 Destination;
01514     ULONG Length;
01515     STRING MessageHeader;
01516     PUCHAR Source;
01517     ULONG_PTR Opaque;
01518 
01519     
01520     
01521     
01522 
01523     Length = AdditionalData->Length;
01524 
01525 
#if defined(_MIPS_) || defined(_ALPHA_)
01526 
01527     Destination = (UCHAR * POINTER_64)m->u.WriteMemory64.TargetBaseAddress;
01528     Source = AdditionalData->Buffer;
01529     
while (Length > 0) {
01530         
if ((Address = 
MmDbgWriteCheck64(Destination, &Opaque)) == NULL64) {
01531             
break;
01532         }
01533 
01534         *Address = *Source++;
01535         Destination += 1;
01536         Length -= 1;
01537     }
01538 
01539 
#endif
01540 
01541     
01542     
01543     
01544     
01545 
01546     m->ReturnStatus = STATUS_SUCCESS;
01547     
if (Length != 0) {
01548         m->ReturnStatus = STATUS_UNSUCCESSFUL;
01549     }
01550 
01551     
01552     
01553     
01554     
01555 
01556     m->u.WriteMemory64.ActualBytesWritten = AdditionalData->Length - Length;
01557     MessageHeader.Length = 
sizeof(DBGKD_MANIPULATE_STATE64);
01558     MessageHeader.Buffer = (PCHAR)m;
01559     
KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
01560                   &MessageHeader,
01561                   NULL);
01562 
01563     
return;
01564 }
01565 
#endif
01566 
01567 
01568 
VOID
01569 KdpGetContext(
01570     IN PDBGKD_MANIPULATE_STATE64 m,
01571     IN PSTRING AdditionalData,
01572     IN PCONTEXT Context
01573     )
01574 
01575 
01576 
01577 
01578 
01579 
01580 
01581 
01582 
01583 
01584 
01585 
01586 
01587 
01588 
01589 
01590 
01591 
01592 
01593 
01594 
01595 
01596 
01597 {
01598     PDBGKD_GET_CONTEXT a = &m->u.GetContext;
01599     STRING MessageHeader;
01600 
01601     MessageHeader.Length = 
sizeof(*m);
01602     MessageHeader.Buffer = (PCHAR)m;
01603 
01604     
ASSERT(AdditionalData->Length == 0);
01605 
01606     
if (m->Processor >= (
USHORT)
KeNumberProcessors) {
01607         m->ReturnStatus = STATUS_UNSUCCESSFUL;
01608     } 
else {
01609         m->ReturnStatus = STATUS_SUCCESS;
01610         AdditionalData->Length = 
sizeof(CONTEXT);
01611         
if (m->Processor == (
USHORT)
KeGetCurrentPrcb()->Number) {
01612             
KdpQuickMoveMemory(AdditionalData->Buffer, (PCHAR)Context, 
sizeof(CONTEXT));
01613         } 
else {
01614             
KdpQuickMoveMemory(AdditionalData->Buffer,
01615                           (PCHAR)&
KiProcessorBlock[m->Processor]->ProcessorState.ContextFrame,
01616                           
sizeof(CONTEXT)
01617                          );
01618         }
01619     }
01620 
01621     
KdpSendPacket(
01622                   PACKET_TYPE_KD_STATE_MANIPULATE,
01623                   &MessageHeader,
01624                   AdditionalData
01625                   );
01626 }
01627 
01628 
VOID
01629 KdpSetContext(
01630     IN PDBGKD_MANIPULATE_STATE64 m,
01631     IN PSTRING AdditionalData,
01632     IN PCONTEXT Context
01633     )
01634 
01635 
01636 
01637 
01638 
01639 
01640 
01641 
01642 
01643 
01644 
01645 
01646 
01647 
01648 
01649 
01650 
01651 
01652 
01653 
01654 
01655 
01656 
01657 {
01658     PDBGKD_SET_CONTEXT a = &m->u.SetContext;
01659     STRING MessageHeader;
01660 
01661     MessageHeader.Length = 
sizeof(*m);
01662     MessageHeader.Buffer = (PCHAR)m;
01663 
01664     
ASSERT(AdditionalData->Length == 
sizeof(CONTEXT));
01665 
01666     
if (m->Processor >= (
USHORT)
KeNumberProcessors) {
01667         m->ReturnStatus = STATUS_UNSUCCESSFUL;
01668     } 
else {
01669         m->ReturnStatus = STATUS_SUCCESS;
01670         
if (m->Processor == (
USHORT)
KeGetCurrentPrcb()->Number) {
01671             
KdpQuickMoveMemory((PCHAR)Context, AdditionalData->Buffer, 
sizeof(CONTEXT));
01672         } 
else {
01673             
KdpQuickMoveMemory((PCHAR)&
KiProcessorBlock[m->Processor]->ProcessorState.ContextFrame,
01674                           AdditionalData->Buffer,
01675                           
sizeof(CONTEXT)
01676                          );
01677         }
01678     }
01679 
01680     
KdpSendPacket(
01681                   PACKET_TYPE_KD_STATE_MANIPULATE,
01682                   &MessageHeader,
01683                   
NULL
01684                   );
01685 }
01686 
01687 
VOID
01688 KdpWriteBreakpoint(
01689     IN PDBGKD_MANIPULATE_STATE64 m,
01690     IN PSTRING AdditionalData,
01691     IN PCONTEXT Context
01692     )
01693 
01694 
01695 
01696 
01697 
01698 
01699 
01700 
01701 
01702 
01703 
01704 
01705 
01706 
01707 
01708 
01709 
01710 
01711 
01712 
01713 
01714 
01715 
01716 {
01717     PDBGKD_WRITE_BREAKPOINT64 a = &m->u.WriteBreakPoint;
01718     STRING MessageHeader;
01719 
01720     MessageHeader.Length = 
sizeof(*m);
01721     MessageHeader.Buffer = (PCHAR)m;
01722 
01723     
ASSERT(AdditionalData->Length == 0);
01724 
01725     a->BreakPointHandle = 
KdpAddBreakpoint((PVOID)a->BreakPointAddress);
01726     
if (a->BreakPointHandle != 0) {
01727         m->ReturnStatus = STATUS_SUCCESS;
01728     } 
else {
01729         m->ReturnStatus = STATUS_UNSUCCESSFUL;
01730     }
01731     
KdpSendPacket(
01732                   PACKET_TYPE_KD_STATE_MANIPULATE,
01733                   &MessageHeader,
01734                   
NULL
01735                   );
01736     UNREFERENCED_PARAMETER(Context);
01737 }
01738 
01739 
VOID
01740 KdpRestoreBreakpoint(
01741     IN PDBGKD_MANIPULATE_STATE64 m,
01742     IN PSTRING AdditionalData,
01743     IN PCONTEXT Context
01744     )
01745 
01746 
01747 
01748 
01749 
01750 
01751 
01752 
01753 
01754 
01755 
01756 
01757 
01758 
01759 
01760 
01761 
01762 
01763 
01764 
01765 
01766 
01767 
01768 {
01769     PDBGKD_RESTORE_BREAKPOINT a = &m->u.RestoreBreakPoint;
01770     STRING MessageHeader;
01771 
01772     MessageHeader.Length = 
sizeof(*m);
01773     MessageHeader.Buffer = (PCHAR)m;
01774 
01775     
ASSERT(AdditionalData->Length == 0);
01776     
if (
KdpDeleteBreakpoint(a->BreakPointHandle)) {
01777         m->ReturnStatus = STATUS_SUCCESS;
01778     } 
else {
01779         m->ReturnStatus = STATUS_UNSUCCESSFUL;
01780     }
01781     
KdpSendPacket(
01782                   PACKET_TYPE_KD_STATE_MANIPULATE,
01783                   &MessageHeader,
01784                   
NULL
01785                   );
01786     UNREFERENCED_PARAMETER(Context);
01787 }
01788 
01789 
#if i386
01790 
long
01791 SymNumFor(
01792     ULONG pc
01793     )
01794 {
01795     ULONG index;
01796 
01797     
for (index = 0; index < 
NumTraceDataSyms; index++) {
01798         
if ((
TraceDataSyms[index].
SymMin <= pc) &&
01799             (
TraceDataSyms[index].
SymMax > pc)) 
return(index);
01800     }
01801     
return(-1);
01802 }
01803 
01804 BOOLEAN TraceDataBufferFilled = 
FALSE;
01805 
01806 
void PotentialNewSymbol (ULONG pc)
01807 {
01808     
if (!TraceDataBufferFilled &&
01809         -1 != SymNumFor(pc)) {     
01810         
return;
01811     }
01812 
01813     TraceDataBufferFilled = 
FALSE;
01814 
01815     
01816     
TraceDataBuffer[
TraceDataBufferPosition].s.LevelChange = 0;
01817 
01818     
if (-1 != SymNumFor(pc)) {
01819         
int sym = SymNumFor(pc);
01820         
TraceDataBuffer[
TraceDataBufferPosition].s.SymbolNumber = (UCHAR) sym;
01821         
KdpCurrentSymbolStart = 
TraceDataSyms[sym].
SymMin;
01822         
KdpCurrentSymbolEnd = 
TraceDataSyms[sym].
SymMax;
01823 
01824         
return;  
01825     }
01826 
01827     
TraceDataSyms[
NextTraceDataSym].
SymMin = 
KdpCurrentSymbolStart;
01828     
TraceDataSyms[
NextTraceDataSym].
SymMax = 
KdpCurrentSymbolEnd;
01829 
01830     
TraceDataBuffer[
TraceDataBufferPosition].s.SymbolNumber = 
NextTraceDataSym;
01831 
01832     
01833     
01834     
NextTraceDataSym = (
NextTraceDataSym + 1) % 256;
01835     
if (
NumTraceDataSyms < 
NextTraceDataSym) {
01836         
NumTraceDataSyms = 
NextTraceDataSym;
01837     }
01838 
01839 }
01840 
01841 
void DumpTraceData(PSTRING MessageData)
01842 {
01843 
01844  
TraceDataBuffer[0].LongNumber = 
TraceDataBufferPosition;
01845  MessageData->Length = 
sizeof(
TraceDataBuffer[0]) * 
TraceDataBufferPosition;
01846  MessageData->Buffer = (PVOID)
TraceDataBuffer;
01847  
TraceDataBufferPosition = 1;
01848 }
01849 
01850 BOOLEAN
01851 TraceDataRecordCallInfo(
01852     ULONG InstructionsTraced,
01853     LONG CallLevelChange,
01854     ULONG pc
01855     )
01856 {
01857     
01858     
01859     
01860 
01861     
long SymNum = SymNumFor(pc);
01862 
01863     
if (
KdpNextCallLevelChange != 0) {
01864         
TraceDataBuffer[
TraceDataBufferPosition].s.LevelChange =
01865                                                 (
char) 
KdpNextCallLevelChange;
01866         
KdpNextCallLevelChange = 0;
01867     }
01868 
01869 
01870     
if (
InstructionsTraced >= TRACE_DATA_INSTRUCTIONS_BIG) {
01871        
TraceDataBuffer[
TraceDataBufferPosition].s.Instructions =
01872            TRACE_DATA_INSTRUCTIONS_BIG;
01873        
TraceDataBuffer[
TraceDataBufferPosition+1].LongNumber =
01874            
InstructionsTraced;
01875        
TraceDataBufferPosition += 2;
01876     } 
else {
01877        
TraceDataBuffer[
TraceDataBufferPosition].s.Instructions =
01878            (
unsigned short)
InstructionsTraced;
01879        
TraceDataBufferPosition++;
01880     }
01881 
01882     
if ((
TraceDataBufferPosition + 2 >= TRACE_DATA_BUFFER_MAX_SIZE) ||
01883         (-1 == SymNum)) {
01884         
if (
TraceDataBufferPosition +2 >= TRACE_DATA_BUFFER_MAX_SIZE) {
01885             TraceDataBufferFilled = 
TRUE;
01886         }
01887        
KdpNextCallLevelChange = 
CallLevelChange;
01888        
return FALSE;
01889     }
01890 
01891     
TraceDataBuffer[
TraceDataBufferPosition].s.LevelChange =(
char)
CallLevelChange;
01892     
TraceDataBuffer[
TraceDataBufferPosition].s.SymbolNumber = (UCHAR) SymNum;
01893     
KdpCurrentSymbolStart = 
TraceDataSyms[SymNum].
SymMin;
01894     
KdpCurrentSymbolEnd = 
TraceDataSyms[SymNum].
SymMax;
01895 
01896     
return TRUE;
01897 }
01898 
01899 BOOLEAN
01900 SkippingWhichBP (
01901     PVOID thread,
01902     PULONG BPNum
01903     )
01904 
01905 
01906 
01907 
01908 
01909 
01910 
01911 {
01912     ULONG index;
01913 
01914     
if (!
IntBPsSkipping) 
return FALSE;
01915 
01916     
for (index = 0; index < 
KdpNumInternalBreakpoints; index++) {
01917         
if (!(
KdpInternalBPs[index].
Flags & DBGKD_INTERNAL_BP_FLAG_INVALID) &&
01918             (
KdpInternalBPs[index].
Thread == thread)) {
01919             *BPNum = index;
01920             
return TRUE;
01921         }
01922     }
01923     
return FALSE; 
01924 }
01925 
01926 
01927 
NTSTATUS
01928 
KdQuerySpecialCalls (
01929     IN PDBGKD_MANIPULATE_STATE64 m,
01930     ULONG Length,
01931     PULONG RequiredLength
01932     )
01933 {
01934     *RequiredLength = 
sizeof(DBGKD_MANIPULATE_STATE64) +
01935                         (
sizeof(ULONG) * 
KdNumberOfSpecialCalls);
01936 
01937     
if ( Length < *RequiredLength ) {
01938         
return STATUS_INFO_LENGTH_MISMATCH;
01939     }
01940 
01941     m->u.QuerySpecialCalls.NumberOfSpecialCalls = 
KdNumberOfSpecialCalls;
01942         RtlCopyMemory(
01943         m + 1,
01944         KdSpecialCalls,
01945         
sizeof(ULONG) * KdNumberOfSpecialCalls
01946         );
01947 
01948     
return STATUS_SUCCESS;
01949 
01950 } 
01951 
01952 
01953 
VOID
01954 
KdSetSpecialCall (
01955     IN PDBGKD_MANIPULATE_STATE64 m,
01956     IN PCONTEXT ContextRecord
01957     )
01958 
01959 
01960 
01961 
01962 
01963 
01964 
01965 
01966 
01967 
01968 
01969 
01970 
01971 
01972 
01973 
01974 
01975 
01976 {
01977     
if ( 
KdNumberOfSpecialCalls >= 
DBGKD_MAX_SPECIAL_CALLS ) {
01978         
return; 
01979     }
01980 
01981     
KdSpecialCalls[
KdNumberOfSpecialCalls++] = (ULONG_PTR)m->u.SetSpecialCall.SpecialCall;
01982 
01983     
NextTraceDataSym = 0;
01984     
NumTraceDataSyms = 0;
01985     
KdpNextCallLevelChange = 0;
01986     
if (ContextRecord && !
InstrCountInternal) {
01987         
InitialSP = ContextRecord->Esp;
01988     }
01989 
01990 } 
01991 
01992 
01993 
VOID
01994 
KdClearSpecialCalls (
01995     VOID
01996     )
01997 
01998 
01999 
02000 
02001 
02002 
02003 
02004 
02005 
02006 
02007 
02008 
02009 
02010 
02011 
02012 
02013 
02014 
02015 
02016 {
02017     
KdNumberOfSpecialCalls = 0;
02018     
return;
02019 
02020 } 
02021 
02022 
02023 BOOLEAN
02024 
KdpCheckTracePoint(
02025     IN PEXCEPTION_RECORD ExceptionRecord,
02026     IN OUT PCONTEXT ContextRecord
02027     )
02028 {
02029     ULONG pc = (ULONG)CONTEXT_TO_PROGRAM_COUNTER(ContextRecord);
02030     LONG BpNum;
02031     ULONG SkippedBPNum;
02032     BOOLEAN AfterSC = 
FALSE;
02033 
02034     
if (ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP) {
02035         
if (
WatchStepOverSuspended) {
02036             
02037             
02038             
02039             
02040             
02041             
02042 
02043             
WatchStepOverHandle = 
KdpAddBreakpoint((PVOID)WatchStepOverBreakAddr);
02044             
WatchStepOverSuspended = 
FALSE;
02045             ContextRecord->EFlags &= ~0x100
L; 
02046             
return TRUE; 
02047         }
02048 
02049         
if ((!
SymbolRecorded) && (
KdpCurrentSymbolStart != 0) && (
KdpCurrentSymbolEnd != 0)) {
02050             
02051             
02052             
02053             
02054             
02055             
02056             
02057 
02058             PotentialNewSymbol(oldpc);
02059             
SymbolRecorded = 
TRUE;
02060         }
02061 
02062         
if (!
InstrCountInternal &&
02063             SkippingWhichBP((PVOID)
KeGetCurrentThread(),&SkippedBPNum)) {
02064 
02065             
02066             
02067             
02068             
02069             
02070             
02071             
02072 
02073             
if (
KdpInternalBPs[SkippedBPNum].
Flags &
02074                 DBGKD_INTERNAL_BP_FLAG_COUNTONLY) {
02075 
02076                 
IntBPsSkipping --;
02077 
02078                 
KdpRestoreAllBreakpoints();
02079 
02080                 ContextRecord->EFlags &= ~0x100
L;  
02081                 
KdpInternalBPs[SkippedBPNum].
Thread = 0;
02082 
02083                 
if (
KdpInternalBPs[SkippedBPNum].
Flags &
02084                         DBGKD_INTERNAL_BP_FLAG_DYING) {
02085                     
KdpDeleteBreakpoint(KdpInternalBPs[SkippedBPNum].Handle);
02086                     
KdpInternalBPs[SkippedBPNum].
Flags |=
02087                             DBGKD_INTERNAL_BP_FLAG_INVALID; 
02088                 }
02089 
02090                 
return TRUE;
02091             }
02092 
02093             
02094             
02095             
02096             
02097             
02098             
02099             
02100             
02101 
02102             
KdpCurrentSymbolEnd = 0;
02103             
KdpCurrentSymbolStart = (ULONG_PTR) 
KdpInternalBPs[SkippedBPNum].
ReturnAddress;
02104 
02105             ContextRecord->EFlags |= 0x100
L; 
02106             
InitialSP = ContextRecord->Esp;
02107 
02108             
InstructionsTraced = 1;  
02109             
InstrCountInternal = 
TRUE;
02110         }
02111 
02112     } 
02113     
else if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) {
02114         
if (
WatchStepOver && pc == 
WatchStepOverBreakAddr) {
02115             
02116             
02117             
02118 
02119             
if ((
WSOThread != (PVOID)
KeGetCurrentThread()) ||
02120                 (
WSOEsp + 0x20 < ContextRecord->Esp) ||
02121                 (ContextRecord->Esp + 0x20 < 
WSOEsp)) {
02122                 
02123                 
02124                 
02125                 
02126                 
02127                 
02128                 
02129                 
02130                 
02131                 
02132                 
02133                 
02134                 
02135                 
02136                 
02137                 
02138                 
02139                 
02140                 
02141                 
02142                 
02143                 
02144                 
02145                 
02146 
02147                 
WatchStepOverSuspended = 
TRUE;
02148                 
KdpDeleteBreakpoint(WatchStepOverHandle);
02149                 ContextRecord->EFlags |= 0x100
L; 
02150                 
return TRUE; 
02151             }
02152 
02153             
02154             
02155             
02156             
02157 
02158             
WatchStepOver = 
FALSE;
02159             
KdpDeleteBreakpoint(WatchStepOverHandle);
02160             ContextRecord->EFlags |= 0x100
L; 
02161             AfterSC = 
TRUE; 
02162 
02163         } 
else {
02164 
02165             
for ( BpNum = 0; BpNum < (LONG) 
KdpNumInternalBreakpoints; BpNum++ ) {
02166                 
if ( !(
KdpInternalBPs[BpNum].
Flags &
02167                        (DBGKD_INTERNAL_BP_FLAG_INVALID |
02168                         DBGKD_INTERNAL_BP_FLAG_SUSPENDED) ) &&
02169                      (
KdpInternalBPs[BpNum].
Addr == pc) ) {
02170                     
break;
02171                 }
02172             }
02173 
02174             
if ( BpNum < (LONG) 
KdpNumInternalBreakpoints ) {
02175 
02176                 
02177                 
02178                 
02179                 
02180                 
02181                 
02182                 
02183 
02184                 
KdpProcessInternalBreakpoint( BpNum );
02185                 
KdpInternalBPs[BpNum].
Thread = (PVOID)
KeGetCurrentThread();
02186                 
IntBPsSkipping ++;
02187 
02188                 
KdpSuspendAllBreakpoints();
02189 
02190                 ContextRecord->EFlags |= 0x100
L;  
02191                 
if (!(
KdpInternalBPs[BpNum].
Flags &
02192                         DBGKD_INTERNAL_BP_FLAG_COUNTONLY)) {
02193                     
KdpInternalBPs[BpNum].
ReturnAddress =
02194                                     
KdpGetReturnAddress( ContextRecord );
02195                 }
02196                 
return TRUE;
02197             }
02198         }
02199     } 
02200 
02201 
02202 
02203 
02204 
02205     
if ((AfterSC || ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP) &&
02206         
KdpCurrentSymbolStart != 0 &&
02207         ((
KdpCurrentSymbolEnd == 0 && ContextRecord->Esp <= 
InitialSP) ||
02208          (
KdpCurrentSymbolStart <= pc && pc < 
KdpCurrentSymbolEnd))) {
02209         ULONG lc;
02210         BOOLEAN IsSpecialCall;
02211 
02212         
02213         
02214         
02215         
02216         
02217 
02218         lc = 
KdpLevelChange( pc, ContextRecord, &IsSpecialCall );
02219         
InstructionsTraced++;
02220         
CallLevelChange += lc;
02221 
02222         
02223         
02224         
02225         
02226 
02227         
if (IsSpecialCall) {
02228 
02229 
02230 
02231             
02232             
02233             
02234             
02235             
02236             
02237             
02238             
02239             
02240             
02241             
02242             
02243 
02244             
if (lc != -1) {
02245                 
CallLevelChange -= lc;
02246             }
02247 
02248             
02249             
02250             
02251 
02252             
WatchStepOver = 
TRUE;
02253             
WatchStepOverBreakAddr = 
KdpGetCallNextOffset( pc, ContextRecord );
02254             
WSOThread = (PVOID)
KeGetCurrentThread( );
02255             
WSOEsp = ContextRecord->Esp;
02256 
02257             
02258             
02259             
02260 
02261             
WatchStepOverHandle = 
KdpAddBreakpoint( (PVOID)WatchStepOverBreakAddr );
02262 
02263 
02264             
02265             
02266             
02267             
02268             
02269 
02270             ContextRecord->EFlags &= ~0x100
L;
02271             
return TRUE;
02272         }
02273 
02274         
02275         
02276         
02277         
02278 
02279         ContextRecord->EFlags |= 0x100
L;  
02280 
02281         
return TRUE;
02282     }
02283 
02284     
if ((AfterSC || (ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP)) &&
02285         (
KdpCurrentSymbolStart != 0)) {
02286         
02287         
02288         
02289         
02290         
02291         
02292         
int lc;
02293         BOOLEAN IsSpecialCall;
02294 
02295         
InstructionsTraced++; 
02296 
02297 
02298 
02299 
02300 
02301         
if (
InstrCountInternal) {
02302 
02303             
02304             
02305 
02306             SkippingWhichBP((PVOID)
KeGetCurrentThread(),&SkippedBPNum);
02307 
02308             
KdpInternalBPs[SkippedBPNum].
Calls++;
02309 
02310 
02311             
if (
KdpInternalBPs[SkippedBPNum].
MinInstructions > 
InstructionsTraced) {
02312                 
KdpInternalBPs[SkippedBPNum].
MinInstructions = 
InstructionsTraced;
02313             }
02314             
if (
KdpInternalBPs[SkippedBPNum].
MaxInstructions < 
InstructionsTraced) {
02315                 
KdpInternalBPs[SkippedBPNum].
MaxInstructions = 
InstructionsTraced;
02316             }
02317             
KdpInternalBPs[SkippedBPNum].
TotalInstructions += 
InstructionsTraced;
02318 
02319             
KdpInternalBPs[SkippedBPNum].
Thread = 0;
02320 
02321             
IntBPsSkipping--;
02322             
InstrCountInternal = 
FALSE;
02323             
KdpCurrentSymbolStart = 0;
02324             
KdpRestoreAllBreakpoints();
02325 
02326             
if (
KdpInternalBPs[SkippedBPNum].
Flags &
02327                     DBGKD_INTERNAL_BP_FLAG_DYING) {
02328                 
KdpDeleteBreakpoint(KdpInternalBPs[SkippedBPNum].Handle);
02329                 
KdpInternalBPs[SkippedBPNum].
Flags |=
02330                         DBGKD_INTERNAL_BP_FLAG_INVALID; 
02331             }
02332 
02333             ContextRecord->EFlags &= ~0x100
L; 
02334             
return TRUE; 
02335         }
02336 
02337         
if (TraceDataRecordCallInfo( InstructionsTraced, CallLevelChange, pc)) {
02338 
02339             
02340             
02341             
02342             
02343             
02344             
02345             
02346             
02347             
02348 
02349             lc = 
KdpLevelChange( pc, ContextRecord, &IsSpecialCall );
02350             
InstructionsTraced = 0;
02351             
CallLevelChange = lc;
02352 
02353             
02354             
02355             
02356             
02357 
02358             
if (IsSpecialCall) {
02359 
02360 
02361 
02362                 
02363                 
02364                 
02365                 
02366                 
02367                 
02368                 
02369                 
02370                 
02371                 
02372                 
02373                 
02374 
02375                 
if (lc != -1) {
02376                     
CallLevelChange -= lc;
02377                 }
02378 
02379                 
02380                 
02381                 
02382 
02383                 
WatchStepOver = 
TRUE;
02384                 
WSOThread = (PVOID)
KeGetCurrentThread();
02385 
02386                 
02387                 
02388                 
02389 
02390                 
WatchStepOverHandle =
02391                     
KdpAddBreakpoint( (PVOID)
KdpGetCallNextOffset( pc, ContextRecord ));
02392 
02393                 
02394                 
02395                 
02396                 
02397 
02398                 ContextRecord->EFlags &= ~0x100
L;
02399                 
return TRUE;
02400             }
02401 
02402             ContextRecord->EFlags |= 0x100
L; 
02403             
return TRUE; 
02404         }
02405 
02406         lc = 
KdpLevelChange( pc, ContextRecord, &IsSpecialCall );
02407         
InstructionsTraced = 0;
02408         
CallLevelChange = lc;
02409 
02410         
02411 
02412         
if ((lc != 0) && IsSpecialCall) {
02413             
02414             
DPRINT(( 
"Special call on first entry to symbol scope @ %x\n", pc ));
02415         }
02416     }
02417 
02418     
SymbolRecorded = 
FALSE;
02419     
oldpc = pc;
02420 
02421     
return FALSE;
02422 }
02423 
#endif // i386
02424 
02425 BOOLEAN
02426 KdpSwitchProcessor (
02427     IN PEXCEPTION_RECORD ExceptionRecord,
02428     IN OUT PCONTEXT ContextRecord,
02429     IN BOOLEAN SecondChance
02430     )
02431 {
02432     BOOLEAN 
Status;
02433 
02434     
02435     
02436     
02437 
02438     
KdPortSave ();
02439 
02440     
02441     
02442     
02443 
02444     
Status = 
KdpReportExceptionStateChange (
02445                 ExceptionRecord,
02446                 ContextRecord,
02447                 SecondChance
02448                 );
02449 
02450     
02451     
02452     
02453 
02454     
KdPortRestore ();
02455     
return Status;
02456 }
02457 
02458 BOOLEAN
02459 KdpReportExceptionStateChange (
02460     IN PEXCEPTION_RECORD ExceptionRecord,
02461     IN OUT PCONTEXT ContextRecord,
02462     IN BOOLEAN SecondChance
02463     )
02464 
02465 
02466 
02467 
02468 
02469 
02470 
02471 
02472 
02473 
02474 
02475 
02476 
02477 
02478 
02479 
02480 
02481 
02482 
02483 
02484 
02485 
02486 
02487 
02488 {
02489     STRING MessageData;
02490     STRING MessageHeader;
02491     DBGKD_WAIT_STATE_CHANGE64 WaitStateChange;
02492     
KCONTINUE_STATUS Status;
02493 
02494 
#if i386
02495 
    if (
KdpCheckTracePoint(ExceptionRecord,ContextRecord)) 
return TRUE;
02496 
#endif
02497 
02498     
do {
02499 
02500         
02501         
02502         
02503 
02504         
KdpSetStateChange(&WaitStateChange,
02505                             ExceptionRecord,
02506                             ContextRecord,
02507                             SecondChance
02508                             );
02509 
02510         MessageHeader.Length = 
sizeof(DBGKD_WAIT_STATE_CHANGE64);
02511         MessageHeader.Buffer = (PCHAR)&WaitStateChange;
02512 
02513 
#if i386
02514 
        
02515         
02516         
02517 
02518         DumpTraceData(&MessageData);
02519 
#else
02520 
        MessageData.Length = 0;
02521 
#endif
02522 
02523         
02524         
02525         
02526         
02527 
02528         
Status = 
KdpSendWaitContinue(
02529                     PACKET_TYPE_KD_STATE_CHANGE64,
02530                     &MessageHeader,
02531                     &MessageData,
02532                     ContextRecord
02533                     );
02534 
02535     } 
while (
Status == 
ContinueProcessorReselected) ;
02536 
02537     
return (BOOLEAN) 
Status;
02538 }
02539 
02540 
02541 BOOLEAN
02542 KdpReportLoadSymbolsStateChange (
02543     IN PSTRING PathName,
02544     IN 
PKD_SYMBOLS_INFO SymbolInfo,
02545     IN BOOLEAN UnloadSymbols,
02546     IN OUT PCONTEXT ContextRecord
02547     )
02548 
02549 
02550 
02551 
02552 
02553 
02554 
02555 
02556 
02557 
02558 
02559 
02560 
02561 
02562 
02563 
02564 
02565 
02566 
02567 
02568 
02569 
02570 
02571 
02572 
02573 
02574 
02575 
02576 
02577 
02578 {
02579 
02580     PSTRING AdditionalData;
02581     STRING MessageData;
02582     STRING MessageHeader;
02583     DBGKD_WAIT_STATE_CHANGE64 WaitStateChange;
02584     
KCONTINUE_STATUS Status;
02585 
02586     
do {
02587 
02588         
02589         
02590         
02591 
02592         WaitStateChange.NewState = DbgKdLoadSymbolsStateChange;
02593         WaitStateChange.ProcessorLevel = 
KeProcessorLevel;
02594         WaitStateChange.Processor = (
USHORT)
KeGetCurrentPrcb()->Number;
02595         WaitStateChange.NumberProcessors = (ULONG)
KeNumberProcessors;
02596         WaitStateChange.Thread = (ULONG64)(LONG64)(LONG_PTR) 
KeGetCurrentThread();
02597         WaitStateChange.ProgramCounter = (ULONG64)(LONG64)(LONG_PTR) CONTEXT_TO_PROGRAM_COUNTER(ContextRecord);
02598         
KdpSetLoadState(&WaitStateChange, ContextRecord);
02599         WaitStateChange.u.LoadSymbols.UnloadSymbols = UnloadSymbols;
02600         WaitStateChange.u.LoadSymbols.BaseOfDll = (ULONG64)SymbolInfo->BaseOfDll;
02601         WaitStateChange.u.LoadSymbols.ProcessId = (ULONG) SymbolInfo->ProcessId;
02602         WaitStateChange.u.LoadSymbols.CheckSum = SymbolInfo->CheckSum;
02603         WaitStateChange.u.LoadSymbols.SizeOfImage = SymbolInfo->SizeOfImage;
02604         
if (ARGUMENT_PRESENT( PathName )) {
02605             WaitStateChange.u.LoadSymbols.PathNameLength =
02606                 
KdpMoveMemory(
02607                     (PCHAR)
KdpPathBuffer,
02608                     (PCHAR)PathName->Buffer,
02609                     PathName->Length
02610                     ) + 1;
02611 
02612             MessageData.Buffer = 
KdpPathBuffer;
02613             MessageData.Length = (
USHORT)WaitStateChange.u.LoadSymbols.PathNameLength;
02614             MessageData.Buffer[MessageData.Length-1] = 
'\0';
02615             AdditionalData = &MessageData;
02616         } 
else {
02617             WaitStateChange.u.LoadSymbols.PathNameLength = 0;
02618             AdditionalData = 
NULL;
02619         }
02620 
02621         MessageHeader.Length = 
sizeof(DBGKD_WAIT_STATE_CHANGE64);
02622         MessageHeader.Buffer = (PCHAR)&WaitStateChange;
02623 
02624         
02625         
02626         
02627         
02628 
02629         
Status = 
KdpSendWaitContinue(
02630                     PACKET_TYPE_KD_STATE_CHANGE64,
02631                     &MessageHeader,
02632                     AdditionalData,
02633                     ContextRecord
02634                     );
02635 
02636     } 
while (
Status == 
ContinueProcessorReselected);
02637 
02638     
return (BOOLEAN) 
Status;
02639 }
02640 
02641 
02642 
VOID
02643 KdpReadPhysicalMemory(
02644     IN PDBGKD_MANIPULATE_STATE64 m,
02645     IN PSTRING AdditionalData,
02646     IN PCONTEXT Context
02647     )
02648 
02649 
02650 
02651 
02652 
02653 
02654 
02655 
02656 
02657 
02658 
02659 
02660 
02661 
02662 
02663 
02664 
02665 
02666 
02667 
02668 
02669 
02670 
02671 {
02672     PDBGKD_READ_MEMORY64 a = &m->u.ReadMemory;
02673     ULONG Length;
02674     STRING MessageHeader;
02675     PVOID64 VirtualAddress;
02676     PHYSICAL_ADDRESS Source;
02677     UCHAR UNALIGNED *Destination;
02678     ULONG NumberBytes;
02679     ULONG BytesLeft;
02680 
02681     MessageHeader.Length = 
sizeof(*m);
02682     MessageHeader.Buffer = (PCHAR)m;
02683 
02684     
02685     
02686     
02687 
02688     
ASSERT(AdditionalData->Length == 0);
02689 
02690     
02691     
02692     
02693 
02694     
if (a->TransferCount > (PACKET_MAX_SIZE - 
sizeof(DBGKD_MANIPULATE_STATE64))) {
02695         Length = PACKET_MAX_SIZE - 
sizeof(DBGKD_MANIPULATE_STATE64);
02696     } 
else {
02697         Length = a->TransferCount;
02698     }
02699 
02700     
02701     
02702     
02703     
02704     
02705     
02706     
02707     
02708     
02709 
02710     Source.QuadPart = a->TargetBaseAddress;
02711     Destination = AdditionalData->Buffer;
02712     
while (Length > 0) {
02713         VirtualAddress = 
MmDbgTranslatePhysicalAddress64(Source);
02714         
if (VirtualAddress == NULL64) {
02715             
break;
02716         }
02717         NumberBytes = 
PAGE_SIZE - 
BYTE_OFFSET(Source.LowPart);
02718         
if (NumberBytes > Length) {
02719             NumberBytes = Length;
02720         }
02721 
02722 
#ifdef _ALPHA_
02723 
        BytesLeft = NumberBytes;
02724         
while (BytesLeft > 0) {
02725             __MB();
02726 
02727             
if (((ULONG64)VirtualAddress & 7) == 0 && BytesLeft > 7) {
02728                 *((ULONGLONG UNALIGNED *)Destination)++ =
02729                     *((ULONGLONG * POINTER_64)VirtualAddress)++;
02730                 BytesLeft -= 8;
02731             } 
else {
02732                 
if (((ULONG64)VirtualAddress & 3) == 0 && BytesLeft > 3) {
02733                     *((ULONG UNALIGNED *)Destination)++ =
02734                         *((ULONG * POINTER_64)VirtualAddress)++;
02735                     BytesLeft -= 4;
02736                 } 
else {
02737                     
if (((ULONG64)VirtualAddress & 1) == 0 && BytesLeft > 1) {
02738                         *((
USHORT UNALIGNED *)Destination)++ =
02739                             *((
USHORT * POINTER_64)VirtualAddress)++;
02740                         BytesLeft -= 2;
02741                     } 
else {
02742                         *Destination++ =
02743                             *((UCHAR * POINTER_64)VirtualAddress)++;
02744                         BytesLeft -= 1;
02745                     }
02746                 }
02747             }
02748         }
02749 
#else
02750 
        KdpMoveMemory(Destination, VirtualAddress, NumberBytes);
02751         Destination += NumberBytes;
02752 
02753 
#endif
02754 
        Source.QuadPart += NumberBytes;
02755         Length -= NumberBytes;
02756         AdditionalData->Length += (
USHORT)NumberBytes;
02757     }
02758 
02759     
if (Length == 0) {
02760         m->ReturnStatus = STATUS_SUCCESS;
02761     } 
else {
02762         m->ReturnStatus = STATUS_UNSUCCESSFUL;
02763     }
02764 
02765     a->ActualBytesRead = AdditionalData->Length;
02766 
02767     
KdpSendPacket(
02768                   PACKET_TYPE_KD_STATE_MANIPULATE,
02769                   &MessageHeader,
02770                   AdditionalData
02771                   );
02772     UNREFERENCED_PARAMETER(Context);
02773 
02774 }
02775 
02776 
02777 
02778 
VOID
02779 KdpWritePhysicalMemory(
02780     IN PDBGKD_MANIPULATE_STATE64 m,
02781     IN PSTRING AdditionalData,
02782     IN PCONTEXT Context
02783     )
02784 
02785 
02786 
02787 
02788 
02789 
02790 
02791 
02792 
02793 
02794 
02795 
02796 
02797 
02798 
02799 
02800 
02801 
02802 
02803 
02804 
02805 
02806 
02807 {
02808     PDBGKD_WRITE_MEMORY64 a = &m->u.WriteMemory;
02809     STRING MessageHeader;
02810     ULONG Length;
02811     PVOID64 VirtualAddress;
02812     PHYSICAL_ADDRESS Destination;
02813     UCHAR UNALIGNED *Source;
02814     ULONG NumberBytes;
02815     ULONG BytesLeft;
02816 
02817     MessageHeader.Length = 
sizeof(*m);
02818     MessageHeader.Buffer = (PCHAR)m;
02819 
02820 
02821     Length = a->TransferCount;
02822 
02823     
02824     
02825     
02826     
02827     
02828 
02829     
02830     
02831     
02832     
02833     
02834     
02835     
02836     
02837 
02838     Source = AdditionalData->Buffer;
02839     Destination.QuadPart = a->TargetBaseAddress;
02840     
while (Length > 0) {
02841         VirtualAddress = 
MmDbgTranslatePhysicalAddress64(Destination);
02842         
if (VirtualAddress == NULL64) {
02843             
break;
02844         }
02845         NumberBytes = 
PAGE_SIZE - 
BYTE_OFFSET(Destination.LowPart);
02846         
if (NumberBytes > Length) {
02847             NumberBytes = Length;
02848         }
02849 
#ifdef _ALPHA_
02850 
        BytesLeft = NumberBytes;
02851         
while (BytesLeft > 0) {
02852             
if (((ULONG64)VirtualAddress & 7) == 0 && BytesLeft > 7) {
02853                 *((ULONGLONG * POINTER_64)VirtualAddress)++ =
02854                     *((ULONGLONG UNALIGNED *)Source)++;
02855                 BytesLeft -= 8;
02856             } 
else {
02857                 
if (((ULONG64)VirtualAddress & 3) == 0 && BytesLeft > 3) {
02858                     *((ULONG * POINTER_64)VirtualAddress)++ =
02859                         *((ULONG UNALIGNED *)Source)++;
02860                     BytesLeft -= 4;
02861                 } 
else {
02862                     
if (((ULONG64)VirtualAddress & 1) == 0 && BytesLeft > 1) {
02863                         *((
USHORT * POINTER_64)VirtualAddress)++ =
02864                             *((
USHORT UNALIGNED *)Source)++;
02865                         BytesLeft -= 2;
02866                     } 
else {
02867                         *((UCHAR * POINTER_64)VirtualAddress)++ =
02868                             *(UCHAR UNALIGNED *)Source++;
02869                         BytesLeft -= 1;
02870                     }
02871                 }
02872             }
02873 
02874             __MB();
02875         }
02876 
#else
02877 
        KdpMoveMemory(VirtualAddress, Source, NumberBytes);
02878         Source += NumberBytes;
02879 
02880 
#endif
02881 
        Destination.QuadPart += NumberBytes;
02882         Length -= NumberBytes;
02883         a->ActualBytesWritten += NumberBytes;
02884     }
02885 
02886     
if (Length == 0) {
02887         m->ReturnStatus = STATUS_SUCCESS;
02888     } 
else {
02889         m->ReturnStatus = STATUS_UNSUCCESSFUL;
02890     }
02891 
02892     
KdpSendPacket(
02893                   PACKET_TYPE_KD_STATE_MANIPULATE,
02894                   &MessageHeader,
02895                   
NULL
02896                   );
02897     UNREFERENCED_PARAMETER(Context);
02898 }
02899 
02900 
02901 
02902 
#if i386
02903 
VOID
02904 
KdpProcessInternalBreakpoint (
02905     ULONG BreakpointNumber
02906     )
02907 {
02908     
static BOOLEAN timerStarted = 
FALSE;
02909     LARGE_INTEGER dueTime;
02910 
02911     
if ( !(
KdpInternalBPs[BreakpointNumber].
Flags &
02912            DBGKD_INTERNAL_BP_FLAG_COUNTONLY) ) {
02913         
return;     
02914     }
02915 
02916     
02917     
02918     
02919     
02920 
02921     
if ( !timerStarted ) { 
02922         dueTime.LowPart = (ULONG)(-1 * 10 * 1000 * 1000);
02923         dueTime.HighPart = -1;
02924         
KeInitializeDpc(
02925             &InternalBreakpointCheckDpc,
02926             &InternalBreakpointCheck,
02927             NULL
02928             );
02929         
KeInitializeTimer( &InternalBreakpointTimer );
02930         
KeSetTimer(
02931             &InternalBreakpointTimer,
02932             dueTime,
02933             &InternalBreakpointCheckDpc
02934             );
02935         timerStarted = 
TRUE;
02936     }
02937 
02938     
KdpInternalBPs[BreakpointNumber].
Calls++;
02939 
02940 } 
02941 
#endif
02942 
02943 
02944 
VOID
02945 KdpGetVersion(
02946     IN PDBGKD_MANIPULATE_STATE64 m
02947     )
02948 
02949 
02950 
02951 
02952 
02953 
02954 
02955 
02956 
02957 
02958 
02959 
02960 
02961 
02962 
02963 
02964 
02965 
02966 
02967 
02968 {
02969     STRING                   messageHeader;
02970 
02971 
02972     messageHeader.Length = 
sizeof(*m);
02973     messageHeader.Buffer = (PCHAR)m;
02974 
02975     RtlZeroMemory(&m->u.GetVersion64, 
sizeof(m->u.GetVersion64));
02976     
02977     
02978     
02979     m->u.GetVersion64.MinorVersion = (
short)
NtBuildNumber;
02980     m->u.GetVersion64.MajorVersion = (
short)((
NtBuildNumber >> 28) & 0xFFFFFFF);
02981 
02982     
02983     
02984     
02985     
02986     m->u.GetVersion64.ProtocolVersion = 5;
02987     m->u.GetVersion64.Flags = DBGKD_VERS_FLAG_DATA;
02988 
02989 
#if !defined(NT_UP)
02990 
    m->u.GetVersion64.Flags |= DBGKD_VERS_FLAG_MP;
02991 
#endif
02992 
02993 
#if defined(_M_IX86)
02994 
    m->u.GetVersion64.MachineType = IMAGE_FILE_MACHINE_I386;
02995 
#elif defined(_M_MRX000)
02996 
    m->u.GetVersion64.MachineType = IMAGE_FILE_MACHINE_R4000;
02997 
#elif defined(_M_ALPHA)
02998 
    m->u.GetVersion64.MachineType = IMAGE_FILE_MACHINE_ALPHA;
02999 
#if defined(_AXP64_)
03000 
    m->u.GetVersion64.Flags |= DBGKD_VERS_FLAG_PTR64;
03001 
#endif
03002 
#elif defined(_M_PPC)
03003 
    m->u.GetVersion64.MachineType = IMAGE_FILE_MACHINE_POWERPC;
03004 
#elif defined(_M_IA64)
03005 
    m->u.GetVersion64.MachineType = IMAGE_FILE_MACHINE_IA64;
03006     m->u.GetVersion64.Flags |= DBGKD_VERS_FLAG_PTR64;
03007 
#else
03008 
#error( "unknown target machine" );
03009 
#endif
03010 
03011     
03012     
03013     
03014     m->u.GetVersion64.PsLoadedModuleList = (ULONG64)(LONG64)(LONG_PTR)&
PsLoadedModuleList;
03015 
03016     
03017     
03018     
03019     
03020     
03021     
03022     
03023     
03024 
03025     
if (
KdpNtosImageBase) {
03026         m->u.GetVersion64.KernBase = (ULONG64)(LONG64)(LONG_PTR)
KdpNtosImageBase;
03027     } 
else {
03028         m->u.GetVersion64.KernBase = (ULONG64)(LONG64)(LONG_PTR)
PsNtosImageBase;
03029     }
03030 
03031     m->u.GetVersion64.DebuggerDataList = (ULONG64)(LONG64)(LONG_PTR)&
KdpDebuggerDataListHead;
03032 
03033     
03034     
03035     
03036     m->ReturnStatus = STATUS_SUCCESS;
03037     m->ApiNumber = DbgKdGetVersionApi;
03038 
03039     
KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE,
03040                   &messageHeader,
03041                   
NULL
03042                  );
03043 
03044     
return;
03045 } 
03046 
03047 
03048 
NTSTATUS
03049 KdpNotSupported(
03050     IN PDBGKD_MANIPULATE_STATE64 m
03051     )
03052 
03053 
03054 
03055 
03056 
03057 
03058 
03059 
03060 
03061 
03062 
03063 
03064 
03065 
03066 
03067 
03068 
03069 {
03070     STRING          MessageHeader;
03071 
03072     
03073     
03074     
03075     MessageHeader.Length = 
sizeof(*m);
03076     MessageHeader.Buffer = (PCHAR)m;
03077     m->ReturnStatus = STATUS_UNSUCCESSFUL;
03078 
03079     
03080     
03081     
03082     
KdpSendPacket(
03083         PACKET_TYPE_KD_STATE_MANIPULATE,
03084         &MessageHeader,
03085         
NULL
03086         );
03087 
03088     
03089     
03090     
03091     
03092     
return 0;
03093 } 
03094 
03095 
03096 
VOID
03097 KdpCauseBugCheck(
03098     IN PDBGKD_MANIPULATE_STATE64 m
03099     )
03100 
03101 
03102 
03103 
03104 
03105 
03106 
03107 
03108 
03109 
03110 
03111 
03112 
03113 
03114 
03115 
03116 
03117 {
03118 
03119     
KeBugCheckEx( MANUALLY_INITIATED_CRASH, 0, 0, 0, 0 );
03120 
03121 } 
03122 
03123 
03124 
NTSTATUS
03125 KdpWriteBreakPointEx(
03126     IN PDBGKD_MANIPULATE_STATE64 m,
03127     IN PSTRING AdditionalData,
03128     IN PCONTEXT Context
03129     )
03130 
03131 
03132 
03133 
03134 
03135 
03136 
03137 
03138 
03139 
03140 
03141 
03142 
03143 
03144 
03145 
03146 
03147 
03148 
03149 
03150 
03151 
03152 
03153 
03154 
03155 
03156 
03157 
03158 
03159 
03160 
03161 
03162 {
03163     PDBGKD_BREAKPOINTEX       a = &m->u.BreakPointEx;
03164     PDBGKD_WRITE_BREAKPOINT64 b;
03165     STRING                    MessageHeader;
03166     ULONG                     i;
03167     DBGKD_WRITE_BREAKPOINT64  BpBuf[BREAKPOINT_TABLE_SIZE];
03168 
03169 
03170     MessageHeader.Length = 
sizeof(*m);
03171     MessageHeader.Buffer = (PCHAR)m;
03172 
03173     
03174     
03175     
03176     
if (AdditionalData->Length !=
03177                          a->BreakPointCount*
sizeof(DBGKD_WRITE_BREAKPOINT64)) {
03178         m->ReturnStatus = STATUS_UNSUCCESSFUL;
03179         
KdpSendPacket(
03180                       PACKET_TYPE_KD_STATE_MANIPULATE,
03181                       &MessageHeader,
03182                       AdditionalData
03183                       );
03184         
return m->ReturnStatus;
03185     }
03186 
03187     
KdpMoveMemory((PUCHAR)BpBuf,
03188                   AdditionalData->Buffer,
03189                   a->BreakPointCount*
sizeof(DBGKD_WRITE_BREAKPOINT64));
03190 
03191     
03192     
03193     
03194     m->ReturnStatus = STATUS_SUCCESS;
03195 
03196     
03197     
03198     
03199     
03200     b = BpBuf;
03201     
for (i=0; i<a->BreakPointCount; i++,b++) {
03202         
if (b->BreakPointHandle) {
03203             
if (!
KdpDeleteBreakpoint(b->BreakPointHandle)) {
03204                 m->ReturnStatus = STATUS_UNSUCCESSFUL;
03205             }
03206             b->BreakPointHandle = 0;
03207         }
03208     }
03209 
03210     
03211     
03212     
03213     
03214     b = BpBuf;
03215     
for (i=0; i<a->BreakPointCount; i++,b++) {
03216         
if (b->BreakPointAddress) {
03217             b->BreakPointHandle = 
KdpAddBreakpoint( (PVOID)b->BreakPointAddress );
03218             
if (!b->BreakPointHandle) {
03219                 m->ReturnStatus = STATUS_UNSUCCESSFUL;
03220             }
03221         }
03222     }
03223 
03224     
03225     
03226     
03227 
03228     
KdpMoveMemory(AdditionalData->Buffer,
03229                   (PUCHAR)BpBuf,
03230                   a->BreakPointCount*
sizeof(DBGKD_WRITE_BREAKPOINT64));
03231 
03232     
KdpSendPacket(
03233                   PACKET_TYPE_KD_STATE_MANIPULATE,
03234                   &MessageHeader,
03235                   AdditionalData
03236                   );
03237 
03238     
03239     
03240     
03241     
03242     
return a->ContinueStatus;
03243 }
03244 
03245 
03246 
VOID
03247 KdpRestoreBreakPointEx(
03248     IN PDBGKD_MANIPULATE_STATE64 m,
03249     IN PSTRING AdditionalData,
03250     IN PCONTEXT Context
03251     )
03252 
03253 
03254 
03255 
03256 
03257 
03258 
03259 
03260 
03261 
03262 
03263 
03264 
03265 
03266 
03267 
03268 
03269 
03270 
03271 
03272 
03273 
03274 {
03275     PDBGKD_BREAKPOINTEX         a = &m->u.BreakPointEx;
03276     PDBGKD_RESTORE_BREAKPOINT   b;
03277     STRING                      MessageHeader;
03278     ULONG                       i;
03279     DBGKD_RESTORE_BREAKPOINT    BpBuf[BREAKPOINT_TABLE_SIZE];
03280 
03281 
03282     MessageHeader.Length = 
sizeof(*m);
03283     MessageHeader.Buffer = (PCHAR)m;
03284 
03285     
03286     
03287     
03288     
if (AdditionalData->Length !=
03289                        a->BreakPointCount*
sizeof(DBGKD_RESTORE_BREAKPOINT)) {
03290         m->ReturnStatus = STATUS_UNSUCCESSFUL;
03291         
KdpSendPacket(
03292                       PACKET_TYPE_KD_STATE_MANIPULATE,
03293                       &MessageHeader,
03294                       AdditionalData
03295                       );
03296         
return;
03297     }
03298 
03299     
KdpMoveMemory((PUCHAR)BpBuf,
03300                   AdditionalData->Buffer,
03301                   a->BreakPointCount*
sizeof(DBGKD_RESTORE_BREAKPOINT));
03302 
03303     
03304     
03305     
03306     m->ReturnStatus = STATUS_SUCCESS;
03307 
03308     
03309     
03310     
03311     
03312     b = BpBuf;
03313     
for (i=0; i<a->BreakPointCount; i++,b++) {
03314         
if (!
KdpDeleteBreakpoint(b->BreakPointHandle)) {
03315             m->ReturnStatus = STATUS_UNSUCCESSFUL;
03316         }
03317     }
03318 
03319     
03320     
03321     
03322     
KdpSendPacket(
03323                   PACKET_TYPE_KD_STATE_MANIPULATE,
03324                   &MessageHeader,
03325                   AdditionalData
03326                   );
03327 }
03328 
03329 
VOID
03330 KdDisableDebugger(
03331     VOID
03332     )
03333 
03334 
03335 
03336 
03337 
03338 
03339 
03340 
03341 
03342 
03343 
03344 
03345 
03346 
03347 
03348 
03349 {
03350     KIRQL oldIrql ;
03351 
03352     
KeRaiseIrql(
DISPATCH_LEVEL, &oldIrql) ;
03353     
KdpPortLock();
03354 
03355     
if (!
KdDisableCount) {
03356 
03357         
KdPreviouslyEnabled = 
KdDebuggerEnabled && (!
KdPitchDebugger) ;
03358         
if (
KdDebuggerEnabled) {
03359 
03360             
KdpSuspendAllBreakpoints() ;
03361             
KiDebugRoutine = 
KdpStub;
03362             
KdDebuggerEnabled = 
FALSE ;
03363         }
03364     }
03365     
KdDisableCount++ ;
03366     
KdpPortUnlock();
03367     
KeLowerIrql(oldIrql);
03368 }
03369 
03370 
VOID
03371 KdEnableDebugger(
03372    VOID
03373    )
03374 
03375 
03376 
03377 
03378 
03379 
03380 
03381 
03382 
03383 
03384 
03385 
03386 
03387 
03388 
03389 
03390 {
03391     KIRQL oldIrql ;
03392 
03393     
KeRaiseIrql(
DISPATCH_LEVEL, &oldIrql) ;
03394     
KdpPortLock();
03395 
03396     
ASSERT(
KdDisableCount > 0) ;
03397     
KdDisableCount-- ;
03398 
03399     
if (!
KdDisableCount) {
03400         
if (
KdPreviouslyEnabled) {
03401 
03402             
03403             
03404             
03405             
PoHiberInProgress = 
TRUE ;
03406             
KdInitSystem(
NULL, 
FALSE) ;
03407             
KdpRestoreAllBreakpoints();
03408             
PoHiberInProgress = 
FALSE ;
03409         }
03410     }
03411     
KdpPortUnlock();
03412     
KeLowerIrql(oldIrql);
03413 }
03414 
03415 
03416 
VOID
03417 KdpSearchMemory(
03418     IN PDBGKD_MANIPULATE_STATE64 m,
03419     IN PSTRING AdditionalData,
03420     IN PCONTEXT Context
03421     )
03422 
03423 
03424 
03425 
03426 
03427 
03428 
03429 
03430 
03431 
03432 
03433 
03434 
03435 
03436 
03437 
03438 
03439 
03440 
03441 
03442 
03443 
03444 
03445 
03446 {
03447     PUCHAR 
Pattern = AdditionalData->Buffer;
03448     ULONG_PTR StartAddress = (ULONG_PTR)m->u.SearchMemory.SearchAddress;
03449     ULONG_PTR EndAddress = (ULONG_PTR)(StartAddress + m->u.SearchMemory.SearchLength);
03450     ULONG PatternLength = m->u.SearchMemory.PatternLength;
03451 
03452     STRING MessageHeader;
03453     ULONG MaskIndex;
03454     PUCHAR PatternTail;
03455     PUCHAR DataTail;
03456     ULONG TailLength;
03457     ULONG Data;
03458     ULONG FirstWordPattern[4];
03459     ULONG FirstWordMask[4];
03460 
03461 
03462     
03463     
03464     
03465     
03466     
03467     
03468 
03469     m->ReturnStatus = STATUS_NO_MORE_ENTRIES;
03470 
03471     
03472     
03473     
03474 
03475     
if (PatternLength > 3) {
03476         FirstWordMask[0] = 0xffffffff;
03477     } 
else {
03478         FirstWordMask[0] = 0xffffffff >> (8*(4-PatternLength));
03479     }
03480 
03481     FirstWordMask[1] = FirstWordMask[0] << 8;
03482     FirstWordMask[2] = FirstWordMask[1] << 8;
03483     FirstWordMask[3] = FirstWordMask[2] << 8;
03484 
03485     FirstWordPattern[0] = 0;
03486     
KdpQuickMoveMemory((PVOID)FirstWordPattern,
03487                        
Pattern,
03488                        PatternLength < 5 ? PatternLength : 4);
03489 
03490     FirstWordPattern[1] = FirstWordPattern[0] << 8;
03491     FirstWordPattern[2] = FirstWordPattern[1] << 8;
03492     FirstWordPattern[3] = FirstWordPattern[2] << 8;
03493 
03494 
03495 
03496 
03497 
03498 
03499 
03500 
03501 
03502 
03503 
03504 
03505 
03506 
03507 
03508 
03509     
03510     
03511     
03512 
03513     MaskIndex = (ULONG) (StartAddress & 3);
03514     StartAddress = StartAddress & ~3;
03515 
03516     
03517     
03518     
03519 
03520     
if (
MmDbgReadCheck((PVOID)StartAddress) == 
NULL) {
03521         StartAddress = (StartAddress + 
PAGE_SIZE) & ~(
PAGE_SIZE-1);
03522         MaskIndex = 0;
03523     }
03524 
03525     
while (StartAddress < EndAddress) {
03526 
03527         
03528         
03529         
03530         
if ((StartAddress & (
PAGE_SIZE-1)) == 0) {
03531             
if (
MmDbgReadCheck((PVOID)StartAddress) == 
NULL) {
03532                 StartAddress = StartAddress + 
PAGE_SIZE;
03533                 
continue;
03534             }
03535         }
03536 
03537         
03538         
03539         
03540 
03541         Data = *(ULONG*)StartAddress;
03542 
03543 
03544         
for ( ; MaskIndex < 4; MaskIndex++) {
03545 
03546 
03547             
if ( (Data & FirstWordMask[MaskIndex]) == FirstWordPattern[MaskIndex]) {
03548 
03549                 
03550                 
03551                 
03552 
03553                 
if ( (4-MaskIndex) >= PatternLength ) {
03554 
03555                     
03556                     
03557                     
03558 
03559 
03560                     m->u.SearchMemory.FoundAddress = StartAddress + MaskIndex;
03561                     m->ReturnStatus = STATUS_SUCCESS;
03562                     
goto done;
03563 
03564                 } 
else {
03565 
03566                     
03567                     
03568                     
03569 
03570 
03571                     PatternTail = 
Pattern + 4 - MaskIndex;
03572                     DataTail = (PUCHAR)StartAddress + 4;
03573                     TailLength = PatternLength - 4 + MaskIndex;
03574 
03575 
03576 
03577 
03578 
03579                     
while (TailLength) {
03580                         
if ( ((ULONG_PTR)DataTail & (
PAGE_SIZE-1)) == 0 &&
03581                              
MmDbgReadCheck(DataTail) == 
FALSE) {
03582 
03583                             
break;
03584                         } 
else
03585 {
03586 
03587 
03588                         
if (*DataTail != *PatternTail) {
03589 
03590                             
break;
03591                         } 
else {
03592                             DataTail++;
03593                             PatternTail++;
03594                             TailLength--;
03595                         }
03596 }
03597                     }
03598 
03599                     
if (TailLength == 0) {
03600 
03601                         
03602                         
03603                         
03604 
03605                         m->u.SearchMemory.FoundAddress = StartAddress + MaskIndex;
03606                         m->ReturnStatus = STATUS_SUCCESS;
03607                         
goto done;
03608 
03609                     }
03610                 }
03611             }
03612         }
03613 
03614         StartAddress += 4;
03615         MaskIndex = 0;
03616     }
03617 
03618 done:
03619 
03620     MessageHeader.Length = 
sizeof(*m);
03621     MessageHeader.Buffer = (PCHAR)m;
03622 
03623     
KdpSendPacket(
03624         PACKET_TYPE_KD_STATE_MANIPULATE,
03625         &MessageHeader,
03626         
NULL
03627         );
03628 
03629 }
03630 
03631 
03632 
VOID
03633 KdpCheckLowMemory(
03634     IN PDBGKD_MANIPULATE_STATE64 Message
03635     )
03636 
03637 
03638 
03639 
03640 
03641 
03642 
03643 
03644 
03645 
03646 
03647 
03648 
03649 
03650 
03651 
03652 
03653 
03654 
03655 
03656 
03657 {
03658 
03659 
#if defined (_X86PAE_)
03660 
    LOGICAL
03661         MiCheckPhysicalPagePattern (
03662         PFN_NUMBER Page,
03663         PULONG CorruptionOffset
03664         );
03665 
03666     
extern PFN_NUMBER 
MmLowestPhysicalPage;
03667     
extern PFN_NUMBER 
MmHighestPhysicalPage;
03668     
extern LOGICAL 
MiNoLowMemory;
03669 
#endif // #if defined (_X86PAE_)
03670 
03671 
03672     STRING MessageHeader;
03673     PFN_NUMBER Page;
03674     PHYSICAL_ADDRESS P;
03675     PVOID64 VirtualAddress;
03676     ULONG CorruptionOffset;
03677 
03678     Message->ReturnStatus = STATUS_SUCCESS;
03679     MessageHeader.Length = 
sizeof(*Message);
03680     MessageHeader.Buffer = (PCHAR)Message;
03681     
03682     
if (
KdpSearchPhysicalMemoryRequested()) {
03683       
03684         
03685         
03686         
03687 
03688         
KdpSearchPhysicalPageRange();
03689     }
03690     
else {
03691 
03692         
03693         
03694         
03695 
03696 
#if defined (_X86PAE_)
03697 
03698         
if (
MiNoLowMemory) {
03699 
03700             
for (Page = 
MmLowestPhysicalPage;
03701                 Page < 
MmHighestPhysicalPage && Page < 1024 * 1024;
03702                 Page += 1) {
03703 
03704 
03705                 
if (! MiCheckPhysicalPagePattern (Page, &CorruptionOffset)) {
03706                     Message->ReturnStatus = Page;
03707                     
break;
03708                 }
03709             }
03710         }
03711 
03712 
#endif // #if defined (_X86PAE_)
03713 
    }
03714 
03715     
03716     
03717     
03718 
03719     
KdpSendPacket (
03720         PACKET_TYPE_KD_STATE_MANIPULATE,
03721         &MessageHeader,
03722         
NULL
03723         );
03724 }
03725 
03726 
03727 
03728 
03729 
03730 
03731 
03732 
03733 
03734 ULONG
03735 KdpSearchHammingDistance (
03736     ULONG_PTR Left,
03737     ULONG_PTR Right
03738     )
03739 
03740 
03741 
03742 
03743 
03744 
03745 
03746 
03747 
03748 
03749 
03750 
03751 
03752 
03753 
03754 
03755 
03756 
03757 
03758 
03759 
03760 
03761 
03762 
03763 {
03764     ULONG_PTR Value;
03765     ULONG 
Index;
03766     ULONG Distance;
03767 
03768     Value = Left ^ Right;
03769     Distance = 0;
03770 
03771     
for (
Index = 0; 
Index < 8 * 
sizeof(ULONG_PTR); 
Index++) {
03772 
03773         
if ((Value & (ULONG_PTR)0x01)) {
03774             
03775             Distance += 1;
03776         }
03777 
03778         Value >>= 1;        
03779     }
03780 
03781     
return Distance;
03782 }
03783 
03784 
03785 
03786 LOGICAL
03787 KdpSearchPhysicalPage (
03788     IN PFN_NUMBER PageFrameIndex,
03789     ULONG_PTR RangeStart,
03790     ULONG_PTR RangeEnd,
03791     ULONG Flags
03792     )
03793 
03794 
03795 
03796 
03797 
03798 
03799 
03800 
03801 
03802 
03803 
03804 
03805 
03806 
03807 
03808 
03809 
03810 
03811 
03812 
03813 
03814 
03815 
03816 
03817 
03818 
03819 
03820 
03821 
03822 
03823 {
03824     PCHAR Va;
03825     ULONG 
Index;
03826     PHYSICAL_ADDRESS Pa;
03827     ULONG_PTR Value;
03828 
03829     
03830     
03831     
03832 
03833     Pa.QuadPart = ((ULONGLONG)PageFrameIndex) << 
PAGE_SHIFT;
03834 
03835     Va = (PCHAR) 
MmDbgTranslatePhysicalAddress64 (Pa);
03836 
03837     
for (
Index = 0; 
Index < 
PAGE_SIZE - 
sizeof(ULONG_PTR); 
Index += 1, Va += 1) {
03838 
03839         Value = *((PULONG_PTR)Va);
03840 
03841         
if ((Value >= RangeStart && Value <= RangeEnd) 
03842             || 
KdpSearchHammingDistance(Value, RangeStart) == 1) {
03843 
03844             
if (
KdpSearchPageHitIndex < 
SEARCH_PAGE_HIT_DATABASE_SIZE) {
03845 
03846                 
KdpSearchPageHits[
KdpSearchPageHitIndex] = PageFrameIndex;
03847                 
KdpSearchPageHitOffsets[
KdpSearchPageHitIndex] = 
Index;
03848                 
03849                 
KdpSearchPageHitIndex += 1;
03850             }
03851 
03852             
if ((Flags & 
KDP_SEARCH_ALL_OFFSETS_IN_PAGE)) {
03853 
03854                 
continue;
03855             }
03856             
else {
03857 
03858                 
return TRUE;
03859             }
03860         }
03861     }
03862 
03863     
return FALSE;
03864 }
03865 
03866 
03867 
03868 LOGICAL
03869 KdpSearchPhysicalMemoryRequested (
03870     VOID
03871     )
03872 
03873 
03874 
03875 
03876 
03877 
03878 
03879 
03880 
03881 
03882 
03883 
03884 
03885 
03886 
03887 
03888 
03889 
03890 
03891 
03892 
03893 
03894 {
03895     
if (
KdpSearchInProgress) {
03896         
03897         
return TRUE;
03898     }
03899     
else {
03900 
03901         
return FALSE;
03902     }
03903 
03904 }
03905 
03906 
03907 
03908 LOGICAL
03909 KdpSearchPhysicalPageRange (
03910     VOID
03911     )
03912 
03913 
03914 
03915 
03916 
03917 
03918 
03919 
03920 
03921 
03922 
03923 
03924 
03925 
03926 
03927 
03928 
03929 
03930 
03931 
03932 
03933 
03934 
03935 
03936 
03937 
03938 
03939 
03940 
03941 
03942 {
03943     PFN_NUMBER CurrentFrame;
03944     ULONG Flags;
03945 
03946     
03947     
03948     
03949     
03950 
03951     
if (!
KdpSearchInProgress) {
03952 
03953         
return FALSE;
03954     }
03955 
03956 
03957     Flags = 0;
03958 
03959     
03960     
03961     
03962     
03963     
03964 
03965     
if (
KdpSearchEndPageFrame == 
KdpSearchStartPageFrame) {
03966 
03967         
KdpSearchEndPageFrame += 1;
03968 
03969         Flags |= 
KDP_SEARCH_ALL_OFFSETS_IN_PAGE;
03970     }
03971 
03972     
for (CurrentFrame = 
KdpSearchStartPageFrame; 
03973          CurrentFrame < 
KdpSearchEndPageFrame; 
03974          CurrentFrame += 1) {
03975 
03976         
KdpSearchPhysicalPage (CurrentFrame, 
03977                               
KdpSearchAddressRangeStart,
03978                               
KdpSearchAddressRangeEnd,
03979                               Flags);
03980         
03981     }
03982 
03983     
return TRUE;
03984 }
03985 
03986