Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

kdapi.c File Reference

#include "kdp.h"

Go to the source code of this file.

Defines

#define SHIFT10000   13
#define Convert100nsToMilliseconds(LARGE_INTEGER)

Functions

LARGE_INTEGER KdpQueryPerformanceCounter (IN PKTRAP_FRAME TrapFrame)
VOID KdpProcessInternalBreakpoint (ULONG BreakpointNumber)
NTSTATUS KdQuerySpecialCalls (PDBGKD_MANIPULATE_STATE m, ULONG Length, PULONG RequiredLength)
VOID KdSetSpecialCall (PDBGKD_MANIPULATE_STATE m, PCONTEXT ContextRecord)
VOID KdClearSpecialCalls (VOID)
VOID KdpGetVersion (IN PDBGKD_MANIPULATE_STATE m)
NTSTATUS KdpNotSupported (IN PDBGKD_MANIPULATE_STATE m)
VOID KdpCauseBugCheck (IN PDBGKD_MANIPULATE_STATE m)
NTSTATUS KdpWriteBreakPointEx (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpRestoreBreakPointEx (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpSearchMemory (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
BOOLEAN KdEnterDebugger (IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
VOID KdExitDebugger (IN BOOLEAN Enable)
VOID KdUpdateTimeSlipEvent (PVOID Event)
VOID KdpTimeSlipDpcRoutine (PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
VOID KdpTimeSlipWork (IN PVOID Context)
KCONTINUE_STATUS KdpSendWaitContinue (IN ULONG OutPacketType, IN PSTRING OutMessageHeader, IN PSTRING OutMessageData OPTIONAL, IN OUT PCONTEXT ContextRecord)
VOID KdpReadVirtualMemory (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpReadVirtualMemory64 (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpWriteVirtualMemory (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpWriteVirtualMemory64 (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpGetContext (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpSetContext (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpWriteBreakpoint (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpRestoreBreakpoint (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
BOOLEAN KdpSwitchProcessor (IN PEXCEPTION_RECORD ExceptionRecord, IN OUT PCONTEXT ContextRecord, IN BOOLEAN SecondChance)
BOOLEAN KdpReportExceptionStateChange (IN PEXCEPTION_RECORD ExceptionRecord, IN OUT PCONTEXT ContextRecord, IN BOOLEAN SecondChance)
BOOLEAN KdpReportLoadSymbolsStateChange (IN PSTRING PathName, IN PKD_SYMBOLS_INFO SymbolInfo, IN BOOLEAN UnloadSymbols, IN OUT PCONTEXT ContextRecord)
VOID KdpReadPhysicalMemory (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdpWritePhysicalMemory (IN PDBGKD_MANIPULATE_STATE m, IN PSTRING AdditionalData, IN PCONTEXT Context)
VOID KdDisableDebugger (VOID)
VOID KdEnableDebugger (VOID)

Variables

LARGE_INTEGER Magic10000
LONG KdDisableCount = 0
BOOLEAN KdPreviouslyEnabled


Define Documentation

#define Convert100nsToMilliseconds LARGE_INTEGER   ) 
 

Value:

( \ RtlExtendedMagicDivide( (LARGE_INTEGER), Magic10000, SHIFT10000 ) \ )

Definition at line 48 of file kdapi.c.

Referenced by TimeToDaysAndFraction().

#define SHIFT10000   13
 

Definition at line 47 of file kdapi.c.


Function Documentation

VOID KdClearSpecialCalls VOID   ) 
 

VOID KdDisableDebugger VOID   ) 
 

Definition at line 3240 of file kdapi.c.

References DISPATCH_LEVEL, FALSE, KdDebuggerEnabled, KdDisableCount, KdPitchDebugger, KdpPortLock(), KdpPortUnlock(), KdPreviouslyEnabled, KdpStub(), KdpSuspendAllBreakpoints(), KeLowerIrql(), KeRaiseIrql(), and KiDebugRoutine.

03246 : 03247 03248 This function is called to disable the debugger. 03249 03250 Arguments: 03251 03252 None. 03253 03254 Return Value: 03255 03256 None. 03257 03258 --*/ 03259 03260 { 03261 KIRQL oldIrql ; 03262 03263 KeRaiseIrql(DISPATCH_LEVEL, &oldIrql) ; 03264 KdpPortLock(); 03265 03266 if (!KdDisableCount) { 03267 03268 KdPreviouslyEnabled = KdDebuggerEnabled && (!KdPitchDebugger) ; 03269 if (KdDebuggerEnabled) { 03270 03271 KdpSuspendAllBreakpoints() ; 03272 KiDebugRoutine = KdpStub; 03273 KdDebuggerEnabled = FALSE ; 03274 } 03275 } 03276 KdDisableCount++ ; 03277 KdpPortUnlock(); 03278 KeLowerIrql(oldIrql); 03279 }

VOID KdEnableDebugger VOID   ) 
 

Definition at line 3282 of file kdapi.c.

References ASSERT, DISPATCH_LEVEL, FALSE, KdDisableCount, KdInitSystem(), KdpPortLock(), KdpPortUnlock(), KdpRestoreAllBreakpoints(), KdPreviouslyEnabled, KeLowerIrql(), KeRaiseIrql(), NULL, PoHiberInProgress, and TRUE.

03287 : 03288 03289 This function is called to reenable the debugger after a call to 03290 KdDisableDebugger. 03291 03292 Arguments: 03293 03294 None. 03295 03296 Return Value: 03297 03298 None. 03299 03300 --*/ 03301 { 03302 KIRQL oldIrql ; 03303 03304 KeRaiseIrql(DISPATCH_LEVEL, &oldIrql) ; 03305 KdpPortLock(); 03306 03307 ASSERT(KdDisableCount > 0) ; 03308 KdDisableCount-- ; 03309 03310 if (!KdDisableCount) { 03311 if (KdPreviouslyEnabled) { 03312 03313 // 03314 // Ugly HACKHACK - Make sure the timers aren't reset. 03315 // 03316 PoHiberInProgress = TRUE ; 03317 KdInitSystem(NULL, FALSE) ; 03318 KdpRestoreAllBreakpoints(); 03319 PoHiberInProgress = FALSE ; 03320 } 03321 } 03322 KdpPortUnlock(); 03323 KeLowerIrql(oldIrql); 03324 }

BOOLEAN KdEnterDebugger IN PKTRAP_FRAME  TrapFrame,
IN PKEXCEPTION_FRAME  ExceptionFrame
 

Definition at line 303 of file kdapi.c.

References DPRINT, FALSE, FREEZE_BACKUP, FREEZE_SKIPPED_PROCESSOR, KdEnteredDebugger, KdpDebuggerLock, KdPortSave(), KdpPortLocked, KdpQueryPerformanceCounter(), KdTimerDifference, KdTimerStart, KdTimerStop, KeFreezeExecution(), KiFreezeFlag, KiTryToAcquireSpinLock(), TimeFields, and TRUE.

00310 : 00311 00312 This function is used to enter the kernel debugger. Its purpose 00313 is to freeze all other processors and aqcuire the kernel debugger 00314 comm port. 00315 00316 Arguments: 00317 00318 TrapFrame - Supplies a pointer to a trap frame that describes the 00319 trap. 00320 00321 ExceptionFrame - Supplies a pointer to an exception frame that 00322 describes the trap. 00323 00324 Return Value: 00325 00326 Returns the previous interrupt enable. 00327 00328 --*/ 00329 00330 { 00331 00332 BOOLEAN Enable; 00333 TIME_FIELDS TimeFields; 00334 #if DBG 00335 extern ULONG KiFreezeFlag; 00336 #endif 00337 00338 // 00339 // HACKHACK - do some crude timer support 00340 // but not if called from KdSetOwedBreakpoints() 00341 // 00342 00343 if (TrapFrame) { 00344 KdTimerStop = KdpQueryPerformanceCounter (TrapFrame); 00345 KdTimerDifference.QuadPart = KdTimerStop.QuadPart - KdTimerStart.QuadPart; 00346 } else { 00347 KdTimerStop.QuadPart = 0; 00348 } 00349 00350 // 00351 // Freeze all other processors, raise IRQL to HIGH_LEVEL, and save debug 00352 // port state. We lock the port so that KdPollBreakin and a debugger 00353 // operation don't interfere with each other. 00354 // 00355 00356 Enable = KeFreezeExecution(TrapFrame, ExceptionFrame); 00357 KdpPortLocked = KiTryToAcquireSpinLock(&KdpDebuggerLock); 00358 KdPortSave(); 00359 KdEnteredDebugger = TRUE; 00360 00361 #if DBG 00362 00363 if ((KiFreezeFlag & FREEZE_BACKUP) != 0) { 00364 DPRINT(("FreezeLock was jammed! Backup SpinLock was used!\n")); 00365 } 00366 00367 if ((KiFreezeFlag & FREEZE_SKIPPED_PROCESSOR) != 0) { 00368 DPRINT(("Some processors not frozen in debugger!\n")); 00369 } 00370 00371 if (KdpPortLocked == FALSE) { 00372 DPRINT(("Port lock was not acquired!\n")); 00373 } 00374 00375 #endif 00376 00377 return Enable; 00378 }

VOID KdExitDebugger IN BOOLEAN  Enable  ) 
 

Definition at line 381 of file kdapi.c.

References KdPortRestore(), KdpPortLocked, KdpPortUnlock(), KdpTimeSlipDpc, KdpTimeSlipPending, KdTimerStart, KdTimerStop, KeInsertQueueDpc(), KeQueryPerformanceCounter(), KeThawExecution(), NULL, PoHiberInProgress, and TimeFields.

00387 : 00388 00389 This function is used to exit the kernel debugger. It is the reverse 00390 of KdEnterDebugger. 00391 00392 Arguments: 00393 00394 Enable - Supplies the previous interrupt enable which is to be restored. 00395 00396 Return Value: 00397 00398 None. 00399 00400 --*/ 00401 00402 { 00403 ULONG ElapsedTime; 00404 ULARGE_INTEGER TimeDifference; 00405 TIME_FIELDS TimeFields; 00406 ULONG Pending; 00407 00408 // 00409 // restore stuff and exit 00410 // 00411 00412 KdPortRestore(); 00413 if (KdpPortLocked) { 00414 KdpPortUnlock(); 00415 } 00416 00417 KeThawExecution(Enable); 00418 00419 // 00420 // Do some crude timer support. If KdEnterDebugger didn't 00421 // Query the performance counter, then don't do it here either. 00422 // 00423 00424 if (KdTimerStop.QuadPart == 0) { 00425 KdTimerStart = KdTimerStop; 00426 } else { 00427 KdTimerStart = KeQueryPerformanceCounter(NULL); 00428 } 00429 00430 // 00431 // Process a time slip 00432 // 00433 00434 if (!PoHiberInProgress) { 00435 00436 Pending = InterlockedIncrement(&KdpTimeSlipPending); 00437 00438 // 00439 // If there's wasn't a time slip pending, queue the DPC to handle it 00440 // 00441 00442 if (Pending == 1) { 00443 InterlockedIncrement(&KdpTimeSlipPending); 00444 KeInsertQueueDpc(&KdpTimeSlipDpc, NULL, NULL); 00445 } 00446 } 00447 00448 return; 00449 }

VOID KdpCauseBugCheck IN PDBGKD_MANIPULATE_STATE  m  ) 
 

Definition at line 3007 of file kdapi.c.

References KeBugCheckEx().

03013 : 03014 03015 This routine causes a bugcheck. It is used for testing the debugger. 03016 03017 Arguments: 03018 03019 m - Supplies the state manipulation message. 03020 03021 Return Value: 03022 03023 None. 03024 03025 --*/ 03026 03027 { 03028 03029 KeBugCheckEx( *(PULONG)&m->u, 0, 0, 0, 0 ); 03030 03031 } // KdCauseBugCheck

VOID KdpGetContext IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1461 of file kdapi.c.

01469 : 01470 01471 This function is called in response of a get context state 01472 manipulation message. Its function is to return the current 01473 context. 01474 01475 Arguments: 01476 01477 m - Supplies the state manipulation message. 01478 01479 AdditionalData - Supplies any additional data for the message. 01480 01481 Context - Supplies the current context. 01482 01483 Return Value: 01484 01485 None. 01486 01487 --*/ 01488 01489 { 01490 PDBGKD_GET_CONTEXT a = &m->u.GetContext; 01491 STRING MessageHeader; 01492 01493 MessageHeader.Length = sizeof(*m); 01494 MessageHeader.Buffer = (PCHAR)m; 01495 01496 ASSERT(AdditionalData->Length == 0); 01497 01498 if (m->Processor >= (USHORT)KeNumberProcessors) { 01499 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01500 } else { 01501 m->ReturnStatus = STATUS_SUCCESS; 01502 AdditionalData->Length = sizeof(CONTEXT); 01503 if (m->Processor == (USHORT)KeGetCurrentPrcb()->Number) { 01504 KdpQuickMoveMemory(AdditionalData->Buffer, (PCHAR)Context, sizeof(CONTEXT)); 01505 } else { 01506 KdpQuickMoveMemory(AdditionalData->Buffer, 01507 (PCHAR)&KiProcessorBlock[m->Processor]->ProcessorState.ContextFrame, 01508 sizeof(CONTEXT) 01509 ); 01510 } 01511 } 01512 01513 KdpSendPacket( 01514 PACKET_TYPE_KD_STATE_MANIPULATE, 01515 &MessageHeader, 01516 AdditionalData 01517 ); 01518 }

VOID KdpGetVersion IN PDBGKD_MANIPULATE_STATE  m  ) 
 

Definition at line 2838 of file kdapi.c.

References KdpDebuggerDataListHead, KdpNtosImageBase, KdpSendPacket(), KeUserCallbackDispatcher, KiCallUserMode(), NtBuildNumber, NULL, PsLoadedModuleList, PsNtosImageBase, and RtlpBreakWithStatusInstruction().

02844 : 02845 02846 This function returns to the caller a general information packet 02847 that contains useful information to a debugger. This packet is also 02848 used for a debugger to determine if the writebreakpointex and 02849 readbreakpointex apis are available. 02850 02851 Arguments: 02852 02853 m - Supplies the state manipulation message. 02854 02855 Return Value: 02856 02857 None. 02858 02859 --*/ 02860 02861 { 02862 STRING messageHeader; 02863 02864 02865 messageHeader.Length = sizeof(*m); 02866 messageHeader.Buffer = (PCHAR)m; 02867 02868 RtlZeroMemory(&m->u.GetVersion, sizeof(m->u.GetVersion)); 02869 // 02870 // the current build number 02871 // 02872 m->u.GetVersion.MinorVersion = (short)NtBuildNumber; 02873 m->u.GetVersion.MajorVersion = (short)((NtBuildNumber >> 28) & 0xFFFFFFF); 02874 02875 // 02876 // kd protocol version number. this should be incremented if the 02877 // protocol changes. 02878 // 02879 m->u.GetVersion.ProtocolVersion = 4; 02880 m->u.GetVersion.Flags = DBGKD_VERS_FLAG_DATA; 02881 02882 #if !defined(NT_UP) 02883 m->u.GetVersion.Flags |= DBGKD_VERS_FLAG_MP; 02884 #endif 02885 02886 #if defined(_M_IX86) 02887 m->u.GetVersion.MachineType = IMAGE_FILE_MACHINE_I386; 02888 #elif defined(_M_MRX000) 02889 m->u.GetVersion.MachineType = IMAGE_FILE_MACHINE_R4000; 02890 #elif defined(_M_ALPHA) 02891 m->u.GetVersion.MachineType = IMAGE_FILE_MACHINE_ALPHA; 02892 #if defined (_AXP64_) 02893 m->u.GetVersion.Flags |= DBGKD_VERS_FLAG_PTR64; 02894 #endif 02895 #elif defined(_M_PPC) 02896 m->u.GetVersion.MachineType = IMAGE_FILE_MACHINE_POWERPC; 02897 #elif defined(_M_IA64) 02898 m->u.GetVersion.MachineType = IMAGE_FILE_MACHINE_IA64; 02899 m->u.GetVersion.Flags |= DBGKD_VERS_FLAG_PTR64; 02900 #else 02901 #error( "unknown target machine" ); 02902 #endif 02903 02904 // 02905 // address of the loader table 02906 // 02907 m->u.GetVersion.PsLoadedModuleList = (ULONG_PTR)&PsLoadedModuleList; 02908 02909 // 02910 // If the debugger is being initialized during boot, PsNtosImageBase 02911 // and PsLoadedModuleList are not yet valid. KdInitSystem got 02912 // the image base from the loader block. 02913 // On the other hand, if the debugger was initialized by a bugcheck, 02914 // it didn't get a loader block to look at, but the system was 02915 // running so the other variables are valid. 02916 // 02917 if (KdpNtosImageBase) { 02918 m->u.GetVersion.KernBase = (ULONG_PTR)KdpNtosImageBase; 02919 } else { 02920 m->u.GetVersion.KernBase = (ULONG_PTR)PsNtosImageBase; 02921 } 02922 02923 // 02924 // These fields are obsolete with the introduction of 02925 // KdDebuggerDataBlock. They are being kept for a while 02926 // so people can still use their 4.0 debuggers. 02927 // 02928 m->u.GetVersion.ThCallbackStack = FIELD_OFFSET(KTHREAD, CallbackStack); 02929 m->u.GetVersion.KiCallUserMode = (ULONG_PTR)KiCallUserMode; 02930 m->u.GetVersion.KeUserCallbackDispatcher = (ULONG_PTR) KeUserCallbackDispatcher; 02931 m->u.GetVersion.NextCallback = FIELD_OFFSET(KCALLOUT_FRAME, CbStk); 02932 #if defined(_X86_) 02933 m->u.GetVersion.FramePointer = FIELD_OFFSET(KCALLOUT_FRAME, Ebp); 02934 #endif 02935 m->u.GetVersion.BreakpointWithStatus = (ULONG_PTR)RtlpBreakWithStatusInstruction; 02936 02937 02938 02939 02940 02941 m->u.GetVersion.DebuggerDataList = (ULONG_PTR)&KdpDebuggerDataListHead; 02942 02943 // 02944 // the usual stuff 02945 // 02946 m->ReturnStatus = STATUS_SUCCESS; 02947 m->ApiNumber = DbgKdGetVersionApi; 02948 02949 KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, 02950 &messageHeader, 02951 NULL 02952 ); 02953 02954 return; 02955 } // KdGetVersion

NTSTATUS KdpNotSupported IN PDBGKD_MANIPULATE_STATE  m  ) 
 

Definition at line 2959 of file kdapi.c.

References KdpSendPacket(), and NULL.

02964 : 02965 02966 This routine returns STATUS_UNSUCCESSFUL to the debugger 02967 02968 Arguments: 02969 02970 m - Supplies a DBGKD_MANIPULATE_STATE struct to answer with 02971 02972 Return Value: 02973 02974 0, to indicate that the system should not continue 02975 02976 --*/ 02977 { 02978 02979 STRING MessageHeader; 02980 // 02981 // setup packet 02982 // 02983 MessageHeader.Length = sizeof(*m); 02984 MessageHeader.Buffer = (PCHAR)m; 02985 m->ReturnStatus = STATUS_UNSUCCESSFUL; 02986 02987 // 02988 // send back our response 02989 // 02990 KdpSendPacket( 02991 PACKET_TYPE_KD_STATE_MANIPULATE, 02992 &MessageHeader, 02993 NULL 02994 ); 02995 02996 // 02997 // return the caller's continue status value. if this is a non-zero 02998 // value the system is continued using this value as the continuestatus. 02999 // 03000 03001 return 0; 03002 03003 } // KdpNotSupported

VOID KdpProcessInternalBreakpoint ULONG  BreakpointNumber  ) 
 

LARGE_INTEGER KdpQueryPerformanceCounter IN PKTRAP_FRAME  TrapFrame  ) 
 

Definition at line 24 of file alpha/kdcmsup.c.

00030 : 00031 00032 This function returns the current value of the system performance 00033 counter. 00034 00035 Arguments: 00036 00037 None. 00038 00039 Return Value: 00040 00041 The value returned by KeQueryPerformanceCounter is returned as the 00042 function value. 00043 00044 --*/ 00045 00046 { 00047 00048 return KeQueryPerformanceCounter(0); 00049 } }

VOID KdpReadPhysicalMemory IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 2534 of file kdapi.c.

02542 : 02543 02544 This function is called in response to a read physical memory 02545 state manipulation message. Its function is to read physical memory 02546 and return. 02547 02548 N.B. This is now more dangerous than ever: if the modified physical 02549 memory is mapped to a virtual page which is protected as readonly text, 02550 the memory manager will eventually bugcheck when it discovers that 02551 the page has been modified. 02552 02553 Arguments: 02554 02555 m - Supplies the state manipulation message. 02556 02557 AdditionalData - Supplies any additional data for the message. 02558 02559 Context - Supplies the current context. 02560 02561 Return Value: 02562 02563 None. 02564 02565 --*/ 02566 02567 { 02568 PDBGKD_READ_MEMORY a = &m->u.ReadMemory; 02569 ULONG Length; 02570 STRING MessageHeader; 02571 PVOID VirtualAddress; 02572 PHYSICAL_ADDRESS Source; 02573 PUCHAR Destination; 02574 USHORT NumberBytes; 02575 USHORT BytesLeft; 02576 02577 MessageHeader.Length = sizeof(*m); 02578 MessageHeader.Buffer = (PCHAR)m; 02579 02580 // 02581 // make sure that nothing but a read memory message was transmitted 02582 // 02583 02584 ASSERT(AdditionalData->Length == 0); 02585 02586 // 02587 // Trim transfer count to fit in a single message 02588 // 02589 02590 if (a->TransferCount > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE))) { 02591 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE); 02592 } else { 02593 Length = a->TransferCount; 02594 } 02595 02596 // 02597 // Since the MmDbgTranslatePhysicalAddress only maps in one physical 02598 // page at a time, we need to break the memory move up into smaller 02599 // moves which don't cross page boundaries. There are two cases we 02600 // need to deal with. The area to be moved may start and end on the 02601 // same page, or it may start and end on different pages (with an 02602 // arbitrary number of pages in between) 02603 // 02604 Source.QuadPart = (ULONG_PTR)a->TargetBaseAddress; 02605 Destination = AdditionalData->Buffer; 02606 BytesLeft = (USHORT)Length; 02607 if(PAGE_ALIGN((PUCHAR)a->TargetBaseAddress) == 02608 PAGE_ALIGN((PUCHAR)(a->TargetBaseAddress)+Length)) { 02609 // 02610 // Memory move starts and ends on the same page. 02611 // 02612 VirtualAddress=MmDbgTranslatePhysicalAddress(Source); 02613 if (VirtualAddress == NULL) { 02614 AdditionalData->Length = 0; 02615 } else { 02616 AdditionalData->Length = (USHORT)KdpMoveMemory( 02617 Destination, 02618 VirtualAddress, 02619 BytesLeft 02620 ); 02621 BytesLeft -= AdditionalData->Length; 02622 } 02623 } else { 02624 // 02625 // Memory move spans page boundaries 02626 // 02627 VirtualAddress=MmDbgTranslatePhysicalAddress(Source); 02628 if (VirtualAddress == NULL) { 02629 AdditionalData->Length = 0; 02630 } else { 02631 NumberBytes = (USHORT)(PAGE_SIZE - BYTE_OFFSET(VirtualAddress)); 02632 AdditionalData->Length = (USHORT)KdpMoveMemory( 02633 Destination, 02634 VirtualAddress, 02635 NumberBytes 02636 ); 02637 Source.LowPart += NumberBytes; 02638 Destination += NumberBytes; 02639 BytesLeft -= NumberBytes; 02640 while(BytesLeft > 0) { 02641 // 02642 // Transfer a full page or the last bit, 02643 // whichever is smaller. 02644 // 02645 VirtualAddress = MmDbgTranslatePhysicalAddress(Source); 02646 if (VirtualAddress == NULL) { 02647 break; 02648 } else { 02649 NumberBytes = (USHORT) ((PAGE_SIZE < BytesLeft) ? PAGE_SIZE : BytesLeft); 02650 AdditionalData->Length += (USHORT)KdpMoveMemory( 02651 Destination, 02652 VirtualAddress, 02653 NumberBytes 02654 ); 02655 Source.LowPart += NumberBytes; 02656 Destination += NumberBytes; 02657 BytesLeft -= NumberBytes; 02658 } 02659 } 02660 } 02661 } 02662 02663 if (Length == AdditionalData->Length) { 02664 m->ReturnStatus = STATUS_SUCCESS; 02665 } else { 02666 m->ReturnStatus = STATUS_UNSUCCESSFUL; 02667 } 02668 a->ActualBytesRead = AdditionalData->Length; 02669 02670 KdpSendPacket( 02671 PACKET_TYPE_KD_STATE_MANIPULATE, 02672 &MessageHeader, 02673 AdditionalData 02674 ); 02675 UNREFERENCED_PARAMETER(Context); 02676 }

VOID KdpReadVirtualMemory IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1139 of file kdapi.c.

01147 : 01148 01149 This function is called in response to a read virtual memory 32-bit 01150 state manipulation message. Its function is to read virtual memory 01151 and return. 01152 01153 Arguments: 01154 01155 m - Supplies a pointer to the state manipulation message. 01156 01157 AdditionalData - Supplies a pointer to a descriptor for the data to read. 01158 01159 Context - Supplies a pointer to the current context. 01160 01161 Return Value: 01162 01163 None. 01164 01165 --*/ 01166 01167 { 01168 01169 ULONG Length; 01170 STRING MessageHeader; 01171 01172 // 01173 // Trim the transfer count to fit in a single message. 01174 // 01175 01176 Length = m->u.ReadMemory.TransferCount; 01177 if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE))) { 01178 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE); 01179 } 01180 01181 // 01182 // Move the data to the destination buffer. 01183 // 01184 01185 AdditionalData->Length = (USHORT)KdpMoveMemory(AdditionalData->Buffer, 01186 m->u.ReadMemory.TargetBaseAddress, 01187 Length); 01188 01189 // 01190 // If all the data is read, then return a success status. Otherwise, 01191 // return unsuccessful. 01192 // 01193 01194 m->ReturnStatus = STATUS_SUCCESS; 01195 if (Length != AdditionalData->Length) { 01196 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01197 } 01198 01199 // 01200 // Set the actual number of bytes read, initialize the message header, 01201 // and send the reply packet to the host debugger. 01202 // 01203 01204 m->u.ReadMemory.ActualBytesRead = AdditionalData->Length; 01205 MessageHeader.Length = sizeof(DBGKD_MANIPULATE_STATE); 01206 MessageHeader.Buffer = (PCHAR)m; 01207 KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, 01208 &MessageHeader, 01209 AdditionalData); 01210 01211 return; 01212 }

VOID KdpReadVirtualMemory64 IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1215 of file kdapi.c.

References KdpSendPacket(), MmDbgReadCheck64(), and USHORT.

Referenced by KdpSendWaitContinue().

01223 : 01224 01225 This function is called in response of a read virtual memory 64-bit 01226 state manipulation message. Its function is to read virtual memory 01227 and return. 01228 01229 Arguments: 01230 01231 m - Supplies a pointer to a state manipulation message. 01232 01233 AdditionalData - Supplies a pointer to descriptor for the data to read. 01234 01235 Context - Supplies a pointer to the current context. 01236 01237 Return Value: 01238 01239 None. 01240 01241 --*/ 01242 01243 { 01244 01245 UCHAR * POINTER_64 Address; 01246 PUCHAR Destination; 01247 ULONG Length; 01248 STRING MessageHeader; 01249 UCHAR * POINTER_64 Source; 01250 01251 // 01252 // Trim the transfer count to fit in a single message. 01253 // 01254 01255 Length = m->u.ReadMemory64.TransferCount; 01256 if (Length > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE))) { 01257 Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE); 01258 } 01259 01260 // 01261 // Move the data to the destination buffer. 01262 // 01263 01264 AdditionalData->Length = (USHORT)Length; 01265 01266 #if defined(_MIPS_) || defined(_ALPHA_) 01267 01268 Destination = AdditionalData->Buffer; 01269 Source = (UCHAR * POINTER_64)m->u.ReadMemory64.TargetBaseAddress; 01270 while (Length > 0) { 01271 if ((Address = MmDbgReadCheck64(Source)) == NULL64) { 01272 break; 01273 } 01274 01275 *Destination++ = *Address; 01276 Source += 1; 01277 Length -= 1; 01278 } 01279 01280 #endif 01281 01282 // 01283 // If all the data is read, then return a success status. Otherwise, 01284 // return an unsuccessful status. 01285 // 01286 01287 m->ReturnStatus = STATUS_SUCCESS; 01288 if (Length != 0) { 01289 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01290 } 01291 01292 // 01293 // Set the actual number of bytes read, initialize the message header, 01294 // and send the reply packet to the host debugger. 01295 // 01296 01297 m->u.ReadMemory64.ActualBytesRead = AdditionalData->Length - Length; 01298 MessageHeader.Length = sizeof(DBGKD_MANIPULATE_STATE); 01299 MessageHeader.Buffer = (PCHAR)m; 01300 KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, 01301 &MessageHeader, 01302 AdditionalData); 01303 01304 return; 01305 }

BOOLEAN KdpReportExceptionStateChange IN PEXCEPTION_RECORD  ExceptionRecord,
IN OUT PCONTEXT  ContextRecord,
IN BOOLEAN  SecondChance
 

Definition at line 2351 of file kdapi.c.

02359 : 02360 02361 This routine sends an exception state change packet to the kernel 02362 debugger and waits for a manipulate state message. 02363 02364 Arguments: 02365 02366 ExceptionRecord - Supplies a pointer to an exception record. 02367 02368 ContextRecord - Supplies a pointer to a context record. 02369 02370 SecondChance - Supplies a boolean value that determines whether this is 02371 the first or second chance for the exception. 02372 02373 Return Value: 02374 02375 A value of TRUE is returned if the exception is handled. Otherwise, a 02376 value of FALSE is returned. 02377 02378 --*/ 02379 02380 { 02381 STRING MessageData; 02382 STRING MessageHeader; 02383 DBGKD_WAIT_STATE_CHANGE WaitStateChange; 02384 KCONTINUE_STATUS Status; 02385 02386 #if i386 02387 if (KdpCheckTracePoint(ExceptionRecord,ContextRecord)) return TRUE; 02388 #endif 02389 02390 do { 02391 02392 // 02393 // Construct the wait state change message and message descriptor. 02394 // 02395 02396 KdpSetStateChange(&WaitStateChange, 02397 ExceptionRecord, 02398 ContextRecord, 02399 SecondChance 02400 ); 02401 02402 MessageHeader.Length = sizeof(DBGKD_WAIT_STATE_CHANGE); 02403 MessageHeader.Buffer = (PCHAR)&WaitStateChange; 02404 02405 #if i386 02406 // 02407 // Construct the wait state change data and data descriptor. 02408 // 02409 02410 DumpTraceData(&MessageData); 02411 #else 02412 MessageData.Length = 0; 02413 #endif 02414 02415 // 02416 // Send packet to the kernel debugger on the host machine, 02417 // wait for answer. 02418 // 02419 02420 Status = KdpSendWaitContinue( 02421 PACKET_TYPE_KD_STATE_CHANGE, 02422 &MessageHeader, 02423 &MessageData, 02424 ContextRecord 02425 ); 02426 02427 } while (Status == ContinueProcessorReselected) ; 02428 02429 return (BOOLEAN) Status; 02430 }

BOOLEAN KdpReportLoadSymbolsStateChange IN PSTRING  PathName,
IN PKD_SYMBOLS_INFO  SymbolInfo,
IN BOOLEAN  UnloadSymbols,
IN OUT PCONTEXT  ContextRecord
 

Definition at line 2434 of file kdapi.c.

02443 : 02444 02445 This routine sends a load symbols state change packet to the kernel 02446 debugger and waits for a manipulate state message. 02447 02448 Arguments: 02449 02450 PathName - Supplies a pointer to the pathname of the image whose 02451 symbols are to be loaded. 02452 02453 BaseOfDll - Supplies the base address where the image was loaded. 02454 02455 ProcessId - Unique 32-bit identifier for process that is using 02456 the symbols. -1 for system process. 02457 02458 CheckSum - Unique 32-bit identifier from image header. 02459 02460 UnloadSymbol - TRUE if the symbols that were previously loaded for 02461 the named image are to be unloaded from the debugger. 02462 02463 Return Value: 02464 02465 A value of TRUE is returned if the exception is handled. Otherwise, a 02466 value of FALSE is returned. 02467 02468 --*/ 02469 02470 { 02471 02472 PSTRING AdditionalData; 02473 STRING MessageData; 02474 STRING MessageHeader; 02475 DBGKD_WAIT_STATE_CHANGE WaitStateChange; 02476 KCONTINUE_STATUS Status; 02477 02478 do { 02479 // 02480 // Construct the wait state change message and message descriptor. 02481 // 02482 02483 WaitStateChange.NewState = DbgKdLoadSymbolsStateChange; 02484 WaitStateChange.ProcessorLevel = KeProcessorLevel; 02485 WaitStateChange.Processor = (USHORT)KeGetCurrentPrcb()->Number; 02486 WaitStateChange.NumberProcessors = (ULONG)KeNumberProcessors; 02487 WaitStateChange.Thread = (PVOID)KeGetCurrentThread(); 02488 WaitStateChange.ProgramCounter = (PVOID)CONTEXT_TO_PROGRAM_COUNTER(ContextRecord); 02489 KdpSetLoadState(&WaitStateChange, ContextRecord); 02490 WaitStateChange.u.LoadSymbols.UnloadSymbols = UnloadSymbols; 02491 WaitStateChange.u.LoadSymbols.BaseOfDll = SymbolInfo->BaseOfDll; 02492 WaitStateChange.u.LoadSymbols.ProcessId = (ULONG)SymbolInfo->ProcessId; 02493 WaitStateChange.u.LoadSymbols.CheckSum = SymbolInfo->CheckSum; 02494 WaitStateChange.u.LoadSymbols.SizeOfImage = SymbolInfo->SizeOfImage; 02495 if (ARGUMENT_PRESENT( PathName )) { 02496 WaitStateChange.u.LoadSymbols.PathNameLength = 02497 KdpMoveMemory( 02498 (PCHAR)KdpPathBuffer, 02499 (PCHAR)PathName->Buffer, 02500 PathName->Length 02501 ) + 1; 02502 02503 MessageData.Buffer = KdpPathBuffer; 02504 MessageData.Length = (USHORT)WaitStateChange.u.LoadSymbols.PathNameLength; 02505 MessageData.Buffer[MessageData.Length-1] = '\0'; 02506 AdditionalData = &MessageData; 02507 } else { 02508 WaitStateChange.u.LoadSymbols.PathNameLength = 0; 02509 AdditionalData = NULL; 02510 } 02511 02512 MessageHeader.Length = sizeof(DBGKD_WAIT_STATE_CHANGE); 02513 MessageHeader.Buffer = (PCHAR)&WaitStateChange; 02514 02515 // 02516 // Send packet to the kernel debugger on the host machine, wait 02517 // for the reply. 02518 // 02519 02520 Status = KdpSendWaitContinue( 02521 PACKET_TYPE_KD_STATE_CHANGE, 02522 &MessageHeader, 02523 AdditionalData, 02524 ContextRecord 02525 ); 02526 02527 } while (Status == ContinueProcessorReselected); 02528 02529 return (BOOLEAN) Status; 02530 }

VOID KdpRestoreBreakpoint IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1632 of file kdapi.c.

01640 : 01641 01642 This function is called in response of a restore breakpoint state 01643 manipulation message. Its function is to restore a breakpoint 01644 using the specified handle. 01645 01646 Arguments: 01647 01648 m - Supplies the state manipulation message. 01649 01650 AdditionalData - Supplies any additional data for the message. 01651 01652 Context - Supplies the current context. 01653 01654 Return Value: 01655 01656 None. 01657 01658 --*/ 01659 01660 { 01661 PDBGKD_RESTORE_BREAKPOINT a = &m->u.RestoreBreakPoint; 01662 STRING MessageHeader; 01663 01664 MessageHeader.Length = sizeof(*m); 01665 MessageHeader.Buffer = (PCHAR)m; 01666 01667 ASSERT(AdditionalData->Length == 0); 01668 if (KdpDeleteBreakpoint(a->BreakPointHandle)) { 01669 m->ReturnStatus = STATUS_SUCCESS; 01670 } else { 01671 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01672 } 01673 KdpSendPacket( 01674 PACKET_TYPE_KD_STATE_MANIPULATE, 01675 &MessageHeader, 01676 NULL 01677 ); 01678 UNREFERENCED_PARAMETER(Context); 01679 }

VOID KdpRestoreBreakPointEx IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 3157 of file kdapi.c.

References KdpDeleteBreakpoint(), KdpMoveMemory(), and KdpSendPacket().

03165 : 03166 03167 This function is called in response of a restore breakpoint state 'ex' 03168 manipulation message. Its function is to clear a list of breakpoints. 03169 03170 Arguments: 03171 03172 m - Supplies the state manipulation message. 03173 03174 AdditionalData - Supplies any additional data for the message. 03175 03176 Context - Supplies the current context. 03177 03178 Return Value: 03179 03180 None. 03181 03182 --*/ 03183 03184 { 03185 PDBGKD_BREAKPOINTEX a = &m->u.BreakPointEx; 03186 PDBGKD_RESTORE_BREAKPOINT b; 03187 STRING MessageHeader; 03188 ULONG i; 03189 DBGKD_RESTORE_BREAKPOINT BpBuf[BREAKPOINT_TABLE_SIZE]; 03190 03191 03192 MessageHeader.Length = sizeof(*m); 03193 MessageHeader.Buffer = (PCHAR)m; 03194 03195 // 03196 // verify that the packet size is correct 03197 // 03198 if (AdditionalData->Length != 03199 a->BreakPointCount*sizeof(DBGKD_RESTORE_BREAKPOINT)) { 03200 m->ReturnStatus = STATUS_UNSUCCESSFUL; 03201 KdpSendPacket( 03202 PACKET_TYPE_KD_STATE_MANIPULATE, 03203 &MessageHeader, 03204 AdditionalData 03205 ); 03206 return; 03207 } 03208 03209 KdpMoveMemory((PUCHAR)BpBuf, 03210 AdditionalData->Buffer, 03211 a->BreakPointCount*sizeof(DBGKD_RESTORE_BREAKPOINT)); 03212 03213 // 03214 // assume success 03215 // 03216 m->ReturnStatus = STATUS_SUCCESS; 03217 03218 // 03219 // loop thru the breakpoint handles passed in from the debugger and 03220 // clear any breakpoint that has a non-zero handle 03221 // 03222 b = BpBuf; 03223 for (i=0; i<a->BreakPointCount; i++,b++) { 03224 if (!KdpDeleteBreakpoint(b->BreakPointHandle)) { 03225 m->ReturnStatus = STATUS_UNSUCCESSFUL; 03226 } 03227 } 03228 03229 // 03230 // send back our response 03231 // 03232 KdpSendPacket( 03233 PACKET_TYPE_KD_STATE_MANIPULATE, 03234 &MessageHeader, 03235 AdditionalData 03236 ); 03237 }

VOID KdpSearchMemory IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 3328 of file kdapi.c.

References FALSE, KdpQuickMoveMemory(), KdpSendPacket(), MmDbgReadCheck(), NULL, PAGE_SIZE, and Pattern.

03336 : 03337 03338 This function implements a memory pattern searcher. This will 03339 find an instance of a pattern that begins in the range 03340 SearchAddress..SearchAddress+SearchLength. The pattern may 03341 end outside of the range. 03342 03343 Arguments: 03344 03345 m - Supplies the state manipulation message. 03346 03347 AdditionalData - Supplies the pattern to search for 03348 03349 Context - Supplies the current context. 03350 03351 Return Value: 03352 03353 None. 03354 03355 --*/ 03356 03357 { 03358 PUCHAR Pattern = AdditionalData->Buffer; 03359 ULONG_PTR StartAddress = (ULONG_PTR)m->u.SearchMemory.SearchAddress; 03360 ULONG_PTR EndAddress = (ULONG_PTR)(StartAddress + m->u.SearchMemory.SearchLength); 03361 ULONG PatternLength = m->u.SearchMemory.PatternLength; 03362 03363 STRING MessageHeader; 03364 ULONG MaskIndex; 03365 PUCHAR PatternTail; 03366 PUCHAR DataTail; 03367 ULONG TailLength; 03368 ULONG Data; 03369 ULONG FirstWordPattern[4]; 03370 ULONG FirstWordMask[4]; 03371 03372 03373 // 03374 // On failure, return STATUS_NO_MORE_ENTRIES. DON'T RETURN 03375 // STATUS_UNSUCCESSFUL! That return status indicates that the 03376 // operation is not supported, and the debugger will fall back 03377 // to a debugger-side search. 03378 // 03379 03380 m->ReturnStatus = STATUS_NO_MORE_ENTRIES; 03381 03382 // 03383 // Do a fast search for the beginning of the pattern 03384 // 03385 03386 if (PatternLength > 3) { 03387 FirstWordMask[0] = 0xffffffff; 03388 } else { 03389 FirstWordMask[0] = 0xffffffff >> (8*(4-PatternLength)); 03390 } 03391 03392 FirstWordMask[1] = FirstWordMask[0] << 8; 03393 FirstWordMask[2] = FirstWordMask[1] << 8; 03394 FirstWordMask[3] = FirstWordMask[2] << 8; 03395 03396 FirstWordPattern[0] = 0; 03397 KdpQuickMoveMemory((PVOID)FirstWordPattern, 03398 Pattern, 03399 PatternLength < 5 ? PatternLength : 4); 03400 03401 FirstWordPattern[1] = FirstWordPattern[0] << 8; 03402 FirstWordPattern[2] = FirstWordPattern[1] << 8; 03403 FirstWordPattern[3] = FirstWordPattern[2] << 8; 03404 03405 03406 /* 03407 { 03408 int i; 03409 for (i = 0; i < (int)PatternLength; i++) { 03410 KdpDprintf("%08x: %02x\n", &Pattern[i], Pattern[i]); 03411 } 03412 for (i = 0; i < 4; i++) { 03413 KdpDprintf("%d: %08x %08x\n", i, FirstWordPattern[i], FirstWordMask[i]); 03414 } 03415 } 03416 */ 03417 03418 03419 03420 // 03421 // Get starting mask 03422 // 03423 03424 MaskIndex = StartAddress & 3; 03425 StartAddress = StartAddress & ~3; 03426 03427 // 03428 // check that the starting page is available 03429 // 03430 03431 if (MmDbgReadCheck((PVOID)StartAddress) == NULL) { 03432 StartAddress = (StartAddress + PAGE_SIZE) & ~(PAGE_SIZE-1); 03433 MaskIndex = 0; 03434 } 03435 03436 while (StartAddress < EndAddress) { 03437 03438 // 03439 // check when starting a new page 03440 // 03441 if ((StartAddress & (PAGE_SIZE-1)) == 0) { 03442 if (MmDbgReadCheck((PVOID)StartAddress) == NULL) { 03443 StartAddress = StartAddress + PAGE_SIZE; 03444 continue; 03445 } 03446 } 03447 03448 // 03449 // search for a match in each of the 4 starting positions 03450 // 03451 03452 Data = *(ULONG*)StartAddress; 03453 //KdpDprintf("\n%08x: %08x ", StartAddress, Data); 03454 03455 for ( ; MaskIndex < 4; MaskIndex++) { 03456 //KdpDprintf(" %d", MaskIndex); 03457 03458 if ( (Data & FirstWordMask[MaskIndex]) == FirstWordPattern[MaskIndex]) { 03459 03460 // 03461 // first word matched 03462 // 03463 03464 if ( (4-MaskIndex) >= PatternLength ) { 03465 03466 // 03467 // string is all in this word; good match 03468 // 03469 //KdpDprintf(" %d hit, complete\n", MaskIndex); 03470 03471 m->u.SearchMemory.FoundAddress = StartAddress + MaskIndex; 03472 m->ReturnStatus = STATUS_SUCCESS; 03473 goto done; 03474 03475 } else { 03476 03477 // 03478 // string is longer; see if tail matches 03479 // 03480 //KdpDprintf(" %d hit, check tail\n", MaskIndex); 03481 03482 PatternTail = Pattern + 4 - MaskIndex; 03483 DataTail = (PUCHAR)StartAddress + 4; 03484 TailLength = PatternLength - 4 + MaskIndex; 03485 03486 //KdpDprintf("Pattern == %08x\n", Pattern); 03487 //KdpDprintf("PatternTail == %08x\n", PatternTail); 03488 //KdpDprintf("DataTail == %08x\n", DataTail); 03489 03490 while (TailLength) { 03491 if ( ((ULONG_PTR)DataTail & (PAGE_SIZE-1)) == 0 && 03492 MmDbgReadCheck(DataTail) == FALSE) { 03493 //KdpDprintf("Tail failed: page not present at %08x\n", DataTail); 03494 break; 03495 } else 03496 { 03497 //KdpDprintf("D: %02x P: %02x\n", *DataTail, *PatternTail); 03498 03499 if (*DataTail != *PatternTail) { 03500 //KdpDprintf("Tail failed at %08x\n", DataTail); 03501 break; 03502 } else { 03503 DataTail++; 03504 PatternTail++; 03505 TailLength--; 03506 } 03507 } 03508 } 03509 03510 if (TailLength == 0) { 03511 03512 // 03513 // A winner 03514 // 03515 03516 m->u.SearchMemory.FoundAddress = StartAddress + MaskIndex; 03517 m->ReturnStatus = STATUS_SUCCESS; 03518 goto done; 03519 03520 } 03521 } 03522 } 03523 } 03524 03525 StartAddress += 4; 03526 MaskIndex = 0; 03527 } 03528 03529 done: 03530 //KdpDprintf("\n"); 03531 MessageHeader.Length = sizeof(*m); 03532 MessageHeader.Buffer = (PCHAR)m; 03533 03534 KdpSendPacket( 03535 PACKET_TYPE_KD_STATE_MANIPULATE, 03536 &MessageHeader, 03537 NULL 03538 ); 03539 03540 } }

KCONTINUE_STATUS KdpSendWaitContinue IN ULONG  OutPacketType,
IN PSTRING  OutMessageHeader,
IN PSTRING OutMessageData  OPTIONAL,
IN OUT PCONTEXT  ContextRecord
 

Definition at line 847 of file kdapi.c.

References ContinueError, ContinueSuccess, FALSE, KCONTINUE_STATUS, KdClearSpecialCalls(), KdDebuggerNotPresent, KDP_MESSAGE_BUFFER_SIZE, KDP_PACKET_RESEND, KDP_PACKET_TIMEOUT, KdpCauseBugCheck(), KdpGetContext(), KdpGetStateChange(), KdpGetVersion(), KdpMessageBuffer, KdpNotSupported(), KdPortRestore(), KdPortSave(), KdpReadControlSpace(), KdpReadIoSpace(), KdpReadIoSpaceExtended(), KdpReadMachineSpecificRegister(), KdpReadPhysicalMemory(), KdpReadVirtualMemory(), KdpReadVirtualMemory64(), KdpReboot(), KdpReceivePacket(), KdpRestoreBreakpoint(), KdpRestoreBreakPointEx(), KdpSearchMemory(), KdpSendPacket(), KdpSetContext(), KdpWriteBreakpoint(), KdpWriteBreakPointEx(), KdpWriteControlSpace(), KdpWriteIoSpace(), KdpWriteIoSpaceExtended(), KdpWriteMachineSpecificRegister(), KdpWritePhysicalMemory(), KdpWriteVirtualMemory(), KdpWriteVirtualMemory64(), KdSetSpecialCall(), KeSwitchFrozenProcessor(), NT_SUCCESS, NTSTATUS(), Status, TRUE, and USHORT.

00856 : 00857 00858 This function sends a packet, and then waits for a continue message. 00859 BreakIns received while waiting will always cause a resend of the 00860 packet originally sent out. While waiting, manipulate messages 00861 will be serviced. 00862 00863 A resend always resends the original event sent to the debugger, 00864 not the last response to some debugger command. 00865 00866 Arguments: 00867 00868 OutPacketType - Supplies the type of packet to send. 00869 00870 OutMessageHeader - Supplies a pointer to a string descriptor that describes 00871 the message information. 00872 00873 OutMessageData - Supplies a pointer to a string descriptor that describes 00874 the optional message data. 00875 00876 ContextRecord - Exception context 00877 00878 Return Value: 00879 00880 A value of TRUE is returned if the continue message indicates 00881 success, Otherwise, a value of FALSE is returned. 00882 00883 --*/ 00884 00885 { 00886 00887 ULONG Length; 00888 STRING MessageData; 00889 STRING MessageHeader; 00890 DBGKD_MANIPULATE_STATE ManipulateState; 00891 ULONG ReturnCode; 00892 NTSTATUS Status; 00893 KCONTINUE_STATUS ContinueStatus; 00894 00895 // 00896 // Loop servicing state manipulation message until a continue message 00897 // is received. 00898 // 00899 00900 MessageHeader.MaximumLength = sizeof(DBGKD_MANIPULATE_STATE); 00901 MessageHeader.Buffer = (PCHAR)&ManipulateState; 00902 MessageData.MaximumLength = KDP_MESSAGE_BUFFER_SIZE; 00903 MessageData.Buffer = (PCHAR)KdpMessageBuffer; 00904 00905 ResendPacket: 00906 00907 // 00908 // Send event notification packet to debugger on host. Come back 00909 // here any time we see a breakin sequence. 00910 // 00911 00912 KdpSendPacket( 00913 OutPacketType, 00914 OutMessageHeader, 00915 OutMessageData 00916 ); 00917 00918 // 00919 // After sending packet, if there is no response from debugger 00920 // AND the packet is for reporting symbol (un)load, the debugger 00921 // will be declared to be not present. Note If the packet is for 00922 // reporting exception, the KdpSendPacket will never stop. 00923 // 00924 00925 if (KdDebuggerNotPresent) { 00926 return ContinueSuccess; 00927 } 00928 00929 while (TRUE) { 00930 00931 // 00932 // Wait for State Manipulate Packet without timeout. 00933 // 00934 00935 do { 00936 00937 ReturnCode = KdpReceivePacket( 00938 PACKET_TYPE_KD_STATE_MANIPULATE, 00939 &MessageHeader, 00940 &MessageData, 00941 &Length 00942 ); 00943 if (ReturnCode == (USHORT)KDP_PACKET_RESEND) { 00944 goto ResendPacket; 00945 } 00946 } while (ReturnCode == KDP_PACKET_TIMEOUT); 00947 00948 // 00949 // Switch on the return message API number. 00950 // 00951 00952 switch (ManipulateState.ApiNumber) { 00953 00954 case DbgKdReadVirtualMemoryApi: 00955 KdpReadVirtualMemory(&ManipulateState,&MessageData,ContextRecord); 00956 break; 00957 00958 case DbgKdReadVirtualMemory64Api: 00959 KdpReadVirtualMemory64(&ManipulateState,&MessageData,ContextRecord); 00960 break; 00961 00962 case DbgKdWriteVirtualMemoryApi: 00963 KdpWriteVirtualMemory(&ManipulateState,&MessageData,ContextRecord); 00964 break; 00965 00966 case DbgKdWriteVirtualMemory64Api: 00967 KdpWriteVirtualMemory64(&ManipulateState,&MessageData,ContextRecord); 00968 break; 00969 00970 case DbgKdReadPhysicalMemoryApi: 00971 KdpReadPhysicalMemory(&ManipulateState,&MessageData,ContextRecord); 00972 break; 00973 00974 case DbgKdWritePhysicalMemoryApi: 00975 KdpWritePhysicalMemory(&ManipulateState,&MessageData,ContextRecord); 00976 break; 00977 00978 case DbgKdGetContextApi: 00979 KdpGetContext(&ManipulateState,&MessageData,ContextRecord); 00980 break; 00981 00982 case DbgKdSetContextApi: 00983 KdpSetContext(&ManipulateState,&MessageData,ContextRecord); 00984 break; 00985 00986 case DbgKdWriteBreakPointApi: 00987 KdpWriteBreakpoint(&ManipulateState,&MessageData,ContextRecord); 00988 break; 00989 00990 case DbgKdRestoreBreakPointApi: 00991 KdpRestoreBreakpoint(&ManipulateState,&MessageData,ContextRecord); 00992 break; 00993 00994 case DbgKdReadControlSpaceApi: 00995 KdpReadControlSpace(&ManipulateState,&MessageData,ContextRecord); 00996 break; 00997 00998 case DbgKdWriteControlSpaceApi: 00999 KdpWriteControlSpace(&ManipulateState,&MessageData,ContextRecord); 01000 break; 01001 01002 case DbgKdReadIoSpaceApi: 01003 KdpReadIoSpace(&ManipulateState,&MessageData,ContextRecord); 01004 break; 01005 01006 case DbgKdWriteIoSpaceApi: 01007 KdpWriteIoSpace(&ManipulateState,&MessageData,ContextRecord); 01008 break; 01009 01010 #ifdef _ALPHA_ 01011 01012 case DbgKdReadIoSpaceExtendedApi: 01013 KdpReadIoSpaceExtended(&ManipulateState,&MessageData,ContextRecord); 01014 break; 01015 01016 case DbgKdWriteIoSpaceExtendedApi: 01017 KdpWriteIoSpaceExtended(&ManipulateState,&MessageData,ContextRecord); 01018 break; 01019 01020 #endif // _ALPHA_ 01021 01022 case DbgKdContinueApi: 01023 if (NT_SUCCESS(ManipulateState.u.Continue.ContinueStatus) != FALSE) { 01024 return ContinueSuccess; 01025 } else { 01026 return ContinueError; 01027 } 01028 break; 01029 01030 case DbgKdContinueApi2: 01031 if (NT_SUCCESS(ManipulateState.u.Continue2.ContinueStatus) != FALSE) { 01032 KdpGetStateChange(&ManipulateState,ContextRecord); 01033 return ContinueSuccess; 01034 } else { 01035 return ContinueError; 01036 } 01037 break; 01038 01039 case DbgKdRebootApi: 01040 KdpReboot(); 01041 break; 01042 01043 #if i386 01044 case DbgKdReadMachineSpecificRegister: 01045 KdpReadMachineSpecificRegister(&ManipulateState,&MessageData,ContextRecord); 01046 break; 01047 01048 case DbgKdWriteMachineSpecificRegister: 01049 KdpWriteMachineSpecificRegister(&ManipulateState,&MessageData,ContextRecord); 01050 break; 01051 01052 case DbgKdSetSpecialCallApi: 01053 KdSetSpecialCall(&ManipulateState,ContextRecord); 01054 break; 01055 01056 case DbgKdClearSpecialCallsApi: 01057 KdClearSpecialCalls(); 01058 break; 01059 01060 case DbgKdSetInternalBreakPointApi: 01061 KdSetInternalBreakpoint(&ManipulateState); 01062 break; 01063 01064 case DbgKdGetInternalBreakPointApi: 01065 KdGetInternalBreakpoint(&ManipulateState); 01066 break; 01067 #endif 01068 01069 case DbgKdGetVersionApi: 01070 KdpGetVersion(&ManipulateState); 01071 break; 01072 01073 case DbgKdCauseBugCheckApi: 01074 KdpCauseBugCheck(&ManipulateState); 01075 break; 01076 01077 case DbgKdPageInApi: 01078 KdpNotSupported(&ManipulateState); 01079 break; 01080 01081 case DbgKdWriteBreakPointExApi: 01082 Status = KdpWriteBreakPointEx(&ManipulateState, 01083 &MessageData, 01084 ContextRecord); 01085 if (Status) { 01086 ManipulateState.ApiNumber = DbgKdContinueApi; 01087 ManipulateState.u.Continue.ContinueStatus = Status; 01088 return ContinueError; 01089 } 01090 break; 01091 01092 case DbgKdRestoreBreakPointExApi: 01093 KdpRestoreBreakPointEx(&ManipulateState,&MessageData,ContextRecord); 01094 break; 01095 01096 case DbgKdSwitchProcessor: 01097 KdPortRestore (); 01098 ContinueStatus = KeSwitchFrozenProcessor(ManipulateState.Processor); 01099 KdPortSave (); 01100 return ContinueStatus; 01101 01102 case DbgKdSearchMemoryApi: 01103 KdpSearchMemory(&ManipulateState, &MessageData, ContextRecord); 01104 break; 01105 01106 // 01107 // Invalid message. 01108 // 01109 01110 default: 01111 MessageData.Length = 0; 01112 ManipulateState.ReturnStatus = STATUS_UNSUCCESSFUL; 01113 KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &MessageHeader, &MessageData); 01114 break; 01115 } 01116 01117 #ifdef _ALPHA_ 01118 01119 // 01120 //jnfix 01121 // this is embarrasing, we have an icache coherency problem that 01122 // the following imb fixes, later we must track this down to the 01123 // exact offending API but for now this statement allows the stub 01124 // work to appropriately for Alpha. 01125 // 01126 01127 #if defined(_MSC_VER) 01128 __PAL_IMB(); 01129 #else 01130 asm( "call_pal 0x86" ); // x86 = imb 01131 #endif 01132 01133 #endif 01134 01135 } 01136 }

VOID KdpSetContext IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1521 of file kdapi.c.

01529 : 01530 01531 This function is called in response of a set context state 01532 manipulation message. Its function is set the current 01533 context. 01534 01535 Arguments: 01536 01537 m - Supplies the state manipulation message. 01538 01539 AdditionalData - Supplies any additional data for the message. 01540 01541 Context - Supplies the current context. 01542 01543 Return Value: 01544 01545 None. 01546 01547 --*/ 01548 01549 { 01550 PDBGKD_SET_CONTEXT a = &m->u.SetContext; 01551 STRING MessageHeader; 01552 01553 MessageHeader.Length = sizeof(*m); 01554 MessageHeader.Buffer = (PCHAR)m; 01555 01556 ASSERT(AdditionalData->Length == sizeof(CONTEXT)); 01557 01558 if (m->Processor >= (USHORT)KeNumberProcessors) { 01559 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01560 } else { 01561 m->ReturnStatus = STATUS_SUCCESS; 01562 if (m->Processor == (USHORT)KeGetCurrentPrcb()->Number) { 01563 KdpQuickMoveMemory((PCHAR)Context, AdditionalData->Buffer, sizeof(CONTEXT)); 01564 } else { 01565 KdpQuickMoveMemory((PCHAR)&KiProcessorBlock[m->Processor]->ProcessorState.ContextFrame, 01566 AdditionalData->Buffer, 01567 sizeof(CONTEXT) 01568 ); 01569 } 01570 } 01571 01572 KdpSendPacket( 01573 PACKET_TYPE_KD_STATE_MANIPULATE, 01574 &MessageHeader, 01575 NULL 01576 ); 01577 }

BOOLEAN KdpSwitchProcessor IN PEXCEPTION_RECORD  ExceptionRecord,
IN OUT PCONTEXT  ContextRecord,
IN BOOLEAN  SecondChance
 

Definition at line 2318 of file kdapi.c.

Referenced by KdInitSystem().

02323 { 02324 BOOLEAN Status; 02325 02326 // 02327 // Save port state 02328 // 02329 02330 KdPortSave (); 02331 02332 // 02333 // Process state change for this processor 02334 // 02335 02336 Status = KdpReportExceptionStateChange ( 02337 ExceptionRecord, 02338 ContextRecord, 02339 SecondChance 02340 ); 02341 02342 // 02343 // Restore port state and return status 02344 // 02345 02346 KdPortRestore (); 02347 return Status; 02348 }

VOID KdpTimeSlipDpcRoutine PKDPC  Dpc,
PVOID  DeferredContext,
PVOID  SystemArgument1,
PVOID  SystemArgument2
 

Definition at line 494 of file kdapi.c.

Referenced by KdInitSystem().

00500 { 00501 LONG OldCount, NewCount, j; 00502 00503 // 00504 // Reset pending count. If the current count is 1, then clear 00505 // the pending count. if the current count is greater then 1, 00506 // then set to one and update the time now. 00507 // 00508 00509 j = KdpTimeSlipPending; 00510 do { 00511 OldCount = j; 00512 NewCount = OldCount > 1 ? 1 : 0; 00513 00514 j = InterlockedCompareExchange(&KdpTimeSlipPending, NewCount, OldCount); 00515 00516 } while (j != OldCount); 00517 00518 // 00519 // If new count is non-zero, then process a time slip now 00520 // 00521 00522 if (NewCount) { 00523 ExQueueWorkItem(&KdpTimeSlipWorkItem, DelayedWorkQueue); 00524 } 00525 }

VOID KdpTimeSlipWork IN PVOID  Context  ) 
 

Definition at line 528 of file kdapi.c.

Referenced by KdInitSystem().

00531 { 00532 KIRQL OldIrql; 00533 LARGE_INTEGER DueTime; 00534 00535 // 00536 // Update time from the real time clock 00537 // 00538 00539 ExAcquireTimeRefreshLock(); 00540 ExUpdateSystemTimeFromCmos (FALSE, 0); 00541 ExReleaseTimeRefreshLock(); 00542 00543 // 00544 // If there's a time service installed, signal it's time slip event 00545 // 00546 00547 KeAcquireSpinLock(&KdpTimeSlipEventLock, &OldIrql); 00548 if (KdpTimeSlipEvent) { 00549 KeSetEvent (KdpTimeSlipEvent, 0, FALSE); 00550 } 00551 KeReleaseSpinLock(&KdpTimeSlipEventLock, OldIrql); 00552 00553 // 00554 // Insert a forced delay between time slip operations 00555 // 00556 00557 DueTime.QuadPart = -1800000000; 00558 KeSetTimer (&KdpTimeSlipTimer, DueTime, &KdpTimeSlipDpc); 00559 }

VOID KdpWriteBreakpoint IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1580 of file kdapi.c.

01588 : 01589 01590 This function is called in response of a write breakpoint state 01591 manipulation message. Its function is to write a breakpoint 01592 and return a handle to the breakpoint. 01593 01594 Arguments: 01595 01596 m - Supplies the state manipulation message. 01597 01598 AdditionalData - Supplies any additional data for the message. 01599 01600 Context - Supplies the current context. 01601 01602 Return Value: 01603 01604 None. 01605 01606 --*/ 01607 01608 { 01609 PDBGKD_WRITE_BREAKPOINT a = &m->u.WriteBreakPoint; 01610 STRING MessageHeader; 01611 01612 MessageHeader.Length = sizeof(*m); 01613 MessageHeader.Buffer = (PCHAR)m; 01614 01615 ASSERT(AdditionalData->Length == 0); 01616 01617 a->BreakPointHandle = KdpAddBreakpoint(a->BreakPointAddress); 01618 if (a->BreakPointHandle != 0) { 01619 m->ReturnStatus = STATUS_SUCCESS; 01620 } else { 01621 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01622 } 01623 KdpSendPacket( 01624 PACKET_TYPE_KD_STATE_MANIPULATE, 01625 &MessageHeader, 01626 NULL 01627 ); 01628 UNREFERENCED_PARAMETER(Context); 01629 }

NTSTATUS KdpWriteBreakPointEx IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 3035 of file kdapi.c.

References KdpAddBreakpoint(), KdpDeleteBreakpoint(), KdpMoveMemory(), and KdpSendPacket().

03043 : 03044 03045 This function is called in response of a write breakpoint state 'ex' 03046 manipulation message. Its function is to clear breakpoints, write 03047 new breakpoints, and continue the target system. The clearing of 03048 breakpoints is conditional based on the presence of breakpoint handles. 03049 The setting of breakpoints is conditional based on the presence of 03050 valid, non-zero, addresses. The continueing of the target system 03051 is conditional based on a non-zero continuestatus. 03052 03053 This api allows a debugger to clear breakpoints, add new breakpoint, 03054 and continue the target system all in one api packet. This reduces the 03055 amount of traffic across the wire and greatly improves source stepping. 03056 03057 03058 Arguments: 03059 03060 m - Supplies the state manipulation message. 03061 03062 AdditionalData - Supplies any additional data for the message. 03063 03064 Context - Supplies the current context. 03065 03066 Return Value: 03067 03068 None. 03069 03070 --*/ 03071 03072 { 03073 PDBGKD_BREAKPOINTEX a = &m->u.BreakPointEx; 03074 PDBGKD_WRITE_BREAKPOINT b; 03075 STRING MessageHeader; 03076 ULONG i; 03077 DBGKD_WRITE_BREAKPOINT BpBuf[BREAKPOINT_TABLE_SIZE]; 03078 03079 03080 MessageHeader.Length = sizeof(*m); 03081 MessageHeader.Buffer = (PCHAR)m; 03082 03083 // 03084 // verify that the packet size is correct 03085 // 03086 if (AdditionalData->Length != 03087 a->BreakPointCount*sizeof(DBGKD_WRITE_BREAKPOINT)) { 03088 m->ReturnStatus = STATUS_UNSUCCESSFUL; 03089 KdpSendPacket( 03090 PACKET_TYPE_KD_STATE_MANIPULATE, 03091 &MessageHeader, 03092 AdditionalData 03093 ); 03094 return m->ReturnStatus; 03095 } 03096 03097 KdpMoveMemory((PUCHAR)BpBuf, 03098 AdditionalData->Buffer, 03099 a->BreakPointCount*sizeof(DBGKD_WRITE_BREAKPOINT)); 03100 03101 // 03102 // assume success 03103 // 03104 m->ReturnStatus = STATUS_SUCCESS; 03105 03106 // 03107 // loop thru the breakpoint handles passed in from the debugger and 03108 // clear any breakpoint that has a non-zero handle 03109 // 03110 b = BpBuf; 03111 for (i=0; i<a->BreakPointCount; i++,b++) { 03112 if (b->BreakPointHandle) { 03113 if (!KdpDeleteBreakpoint(b->BreakPointHandle)) { 03114 m->ReturnStatus = STATUS_UNSUCCESSFUL; 03115 } 03116 b->BreakPointHandle = 0; 03117 } 03118 } 03119 03120 // 03121 // loop thru the breakpoint addesses passed in from the debugger and 03122 // add any new breakpoints that have a non-zero address 03123 // 03124 b = BpBuf; 03125 for (i=0; i<a->BreakPointCount; i++,b++) { 03126 if (b->BreakPointAddress) { 03127 b->BreakPointHandle = KdpAddBreakpoint( b->BreakPointAddress ); 03128 if (!b->BreakPointHandle) { 03129 m->ReturnStatus = STATUS_UNSUCCESSFUL; 03130 } 03131 } 03132 } 03133 03134 // 03135 // send back our response 03136 // 03137 03138 KdpMoveMemory(AdditionalData->Buffer, 03139 (PUCHAR)BpBuf, 03140 a->BreakPointCount*sizeof(DBGKD_WRITE_BREAKPOINT)); 03141 03142 KdpSendPacket( 03143 PACKET_TYPE_KD_STATE_MANIPULATE, 03144 &MessageHeader, 03145 AdditionalData 03146 ); 03147 03148 // 03149 // return the caller's continue status value. if this is a non-zero 03150 // value the system is continued using this value as the continuestatus. 03151 // 03152 return a->ContinueStatus; 03153 }

VOID KdpWritePhysicalMemory IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 2680 of file kdapi.c.

02688 : 02689 02690 This function is called in response to a write physical memory 02691 state manipulation message. Its function is to write physical memory 02692 and return. 02693 02694 Arguments: 02695 02696 m - Supplies the state manipulation message. 02697 02698 AdditionalData - Supplies any additional data for the message. 02699 02700 Context - Supplies the current context. 02701 02702 Return Value: 02703 02704 None. 02705 02706 --*/ 02707 02708 { 02709 PDBGKD_WRITE_MEMORY a = &m->u.WriteMemory; 02710 ULONG Length; 02711 STRING MessageHeader; 02712 PVOID VirtualAddress; 02713 PHYSICAL_ADDRESS Destination; 02714 PUCHAR Source; 02715 USHORT NumberBytes; 02716 USHORT BytesLeft; 02717 02718 MessageHeader.Length = sizeof(*m); 02719 MessageHeader.Buffer = (PCHAR)m; 02720 02721 02722 // 02723 // Since the MmDbgTranslatePhysicalAddress only maps in one physical 02724 // page at a time, we need to break the memory move up into smaller 02725 // moves which don't cross page boundaries. There are two cases we 02726 // need to deal with. The area to be moved may start and end on the 02727 // same page, or it may start and end on different pages (with an 02728 // arbitrary number of pages in between) 02729 // 02730 Destination.QuadPart = (ULONG_PTR)a->TargetBaseAddress; 02731 Source = AdditionalData->Buffer; 02732 BytesLeft = (USHORT) a->TransferCount; 02733 if(PAGE_ALIGN((PUCHAR)Destination.LowPart) == 02734 PAGE_ALIGN((PUCHAR)(Destination.LowPart)+BytesLeft)) { 02735 // 02736 // Memory move starts and ends on the same page. 02737 // 02738 VirtualAddress=MmDbgTranslatePhysicalAddress(Destination); 02739 Length = (USHORT)KdpMoveMemory( 02740 VirtualAddress, 02741 Source, 02742 BytesLeft 02743 ); 02744 BytesLeft -= (USHORT) Length; 02745 } else { 02746 // 02747 // Memory move spans page boundaries 02748 // 02749 VirtualAddress=MmDbgTranslatePhysicalAddress(Destination); 02750 NumberBytes = (USHORT) (PAGE_SIZE - BYTE_OFFSET(VirtualAddress)); 02751 Length = (USHORT)KdpMoveMemory( 02752 VirtualAddress, 02753 Source, 02754 NumberBytes 02755 ); 02756 Source += NumberBytes; 02757 Destination.LowPart += NumberBytes; 02758 BytesLeft -= NumberBytes; 02759 while(BytesLeft > 0) { 02760 // 02761 // Transfer a full page or the last bit, 02762 // whichever is smaller. 02763 // 02764 VirtualAddress = MmDbgTranslatePhysicalAddress(Destination); 02765 NumberBytes = (USHORT) ((PAGE_SIZE < BytesLeft) ? PAGE_SIZE : BytesLeft); 02766 Length += (USHORT)KdpMoveMemory( 02767 VirtualAddress, 02768 Source, 02769 NumberBytes 02770 ); 02771 Source += NumberBytes; 02772 Destination.LowPart += NumberBytes; 02773 BytesLeft -= NumberBytes; 02774 } 02775 } 02776 02777 02778 if (Length == AdditionalData->Length) { 02779 m->ReturnStatus = STATUS_SUCCESS; 02780 } else { 02781 m->ReturnStatus = STATUS_UNSUCCESSFUL; 02782 } 02783 02784 a->ActualBytesWritten = Length; 02785 02786 KdpSendPacket( 02787 PACKET_TYPE_KD_STATE_MANIPULATE, 02788 &MessageHeader, 02789 NULL 02790 ); 02791 UNREFERENCED_PARAMETER(Context); 02792 }

VOID KdpWriteVirtualMemory IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1308 of file kdapi.c.

01316 : 01317 01318 This function is called in response of a write virtual memory 32-bit 01319 state manipulation message. Its function is to write virtual memory 01320 and return. 01321 01322 Arguments: 01323 01324 m - Supplies a pointer to the state manipulation message. 01325 01326 AdditionalData - Supplies a pointer to a descriptor for the data to write. 01327 01328 Context - Supplies a pointer to the current context. 01329 01330 Return Value: 01331 01332 None. 01333 01334 --*/ 01335 01336 { 01337 01338 ULONG Length; 01339 STRING MessageHeader; 01340 01341 // 01342 // Move the data to the destination buffer. 01343 // 01344 01345 Length = KdpMoveMemory(m->u.WriteMemory.TargetBaseAddress, 01346 AdditionalData->Buffer, 01347 AdditionalData->Length); 01348 01349 // 01350 // If all the data is written, then return a success status. Otherwise, 01351 // return an unsuccessful status. 01352 // 01353 01354 m->ReturnStatus = STATUS_SUCCESS; 01355 if (Length != AdditionalData->Length) { 01356 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01357 } 01358 01359 // 01360 // Set the actual number of bytes written, initialize the message header, 01361 // and send the reply packet to the host debugger. 01362 // 01363 01364 m->u.WriteMemory.ActualBytesWritten = Length; 01365 MessageHeader.Length = sizeof(DBGKD_MANIPULATE_STATE); 01366 MessageHeader.Buffer = (PCHAR)m; 01367 KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, 01368 &MessageHeader, 01369 NULL); 01370 01371 return; 01372 }

VOID KdpWriteVirtualMemory64 IN PDBGKD_MANIPULATE_STATE  m,
IN PSTRING  AdditionalData,
IN PCONTEXT  Context
 

Definition at line 1375 of file kdapi.c.

References KdpSendPacket(), MmDbgWriteCheck64(), and NULL.

Referenced by KdpSendWaitContinue().

01383 : 01384 01385 This function is called in response of a write virtual memory 64-bit 01386 state manipulation message. Its function is to write virtual memory 01387 and return. 01388 01389 Arguments: 01390 01391 m - Supplies a pointer to the state manipulation message. 01392 01393 AdditionalData - Supplies a pointer to a descriptor for the data to write. 01394 01395 Context - Supplies a pointer to the current context. 01396 01397 Return Value: 01398 01399 None. 01400 01401 --*/ 01402 01403 { 01404 01405 UCHAR * POINTER_64 Address; 01406 UCHAR * POINTER_64 Destination; 01407 ULONG Length; 01408 STRING MessageHeader; 01409 PUCHAR Source; 01410 ULONG_PTR Opaque; 01411 01412 // 01413 // Move the data to the destination buffer. 01414 // 01415 01416 Length = AdditionalData->Length; 01417 01418 #if defined(_MIPS_) || defined(_ALPHA_) 01419 01420 Destination = (UCHAR * POINTER_64)m->u.WriteMemory64.TargetBaseAddress; 01421 Source = AdditionalData->Buffer; 01422 while (Length > 0) { 01423 if ((Address = MmDbgWriteCheck64(Destination)) == NULL64) { 01424 break; 01425 } 01426 01427 *Address = *Source++; 01428 Destination += 1; 01429 Length -= 1; 01430 } 01431 01432 #endif 01433 01434 // 01435 // If all the data is written, then return a success status. Otherwise, 01436 // return an unsuccessful status. 01437 // 01438 01439 m->ReturnStatus = STATUS_SUCCESS; 01440 if (Length != 0) { 01441 m->ReturnStatus = STATUS_UNSUCCESSFUL; 01442 } 01443 01444 // 01445 // Set the actual number of bytes written, initialize the message header, 01446 // and send the reply packet to the host debugger. 01447 // 01448 01449 m->u.WriteMemory64.ActualBytesWritten = AdditionalData->Length - Length; 01450 MessageHeader.Length = sizeof(DBGKD_MANIPULATE_STATE); 01451 MessageHeader.Buffer = (PCHAR)m; 01452 KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, 01453 &MessageHeader, 01454 NULL); 01455 01456 return; 01457 }

NTSTATUS KdQuerySpecialCalls PDBGKD_MANIPULATE_STATE  m,
ULONG  Length,
PULONG  RequiredLength
 

VOID KdSetSpecialCall PDBGKD_MANIPULATE_STATE  m,
PCONTEXT  ContextRecord
 

VOID KdUpdateTimeSlipEvent PVOID  Event  ) 
 

Definition at line 453 of file kdapi.c.

References Event(), KdpTimeSlipEvent, KdpTimeSlipEventLock, KeAcquireSpinLock, KeReleaseSpinLock(), NULL, and ObDereferenceObject.

00459 : 00460 00461 Update the reference to an event object which will be signalled when 00462 the debugger has caused the system clock to skew. 00463 00464 Arguments: 00465 00466 Event - Supplies a pointer to an event object 00467 00468 Return Value: 00469 00470 None 00471 00472 --*/ 00473 00474 { 00475 KIRQL OldIrql; 00476 00477 KeAcquireSpinLock(&KdpTimeSlipEventLock, &OldIrql); 00478 00479 // 00480 // Dereference the old event and forget about it. 00481 // Remember the new event if there is one. 00482 // 00483 00484 if (KdpTimeSlipEvent != NULL) { 00485 ObDereferenceObject(KdpTimeSlipEvent); 00486 } 00487 00488 KdpTimeSlipEvent = Event; 00489 00490 KeReleaseSpinLock(&KdpTimeSlipEventLock, OldIrql); 00491 }


Variable Documentation

LONG KdDisableCount = 0
 

Definition at line 243 of file kdapi.c.

Referenced by KdDisableDebugger(), and KdEnableDebugger().

BOOLEAN KdPreviouslyEnabled
 

Definition at line 244 of file kdapi.c.

Referenced by KdDisableDebugger(), and KdEnableDebugger().

LARGE_INTEGER Magic10000
 

Definition at line 46 of file kdapi.c.


Generated on Sat May 15 19:44:24 2004 for test by doxygen 1.3.7