test: kdmove.c Source File

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

# kdmove.c

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1990  Microsoft Corporation
    00004
    00005 Module Name:
    00006
    00007     kdmove.c
    00008
    00009 Abstract:
    00010
    00011     This module contains code to implement the portable kernel debugger
    00012     memory mover.
    00013
    00014 Author:
    00015
    00016     Mark Lucovsky (markl) 31-Aug-1990
    00017
    00018 Revision History:
    00019
    00020 --*/
    00021
    00022 #include "kdp.h"
    00023
    00024 #ifdef ALLOC_PRAGMA
    00025 #pragma alloc_text(PAGEKD, KdpMoveMemory)
    00026 #pragma alloc_text(PAGEKD, KdpQuickMoveMemory)
    00027 #endif
    00028
    00029
    00030 ULONG
    00031 KdpMoveMemory (
    00032     IN PCHAR Destination,
    00033     IN PCHAR Source,
    00034     IN ULONG Length
    00035     )
    00036
    00037 /*++
    00038
    00039 Routine Description:
    00040
    00041     This routine moves data to or from the message buffer and returns the
    00042     actual length of the information that was moved. As data is moved, checks
    00043     are made to ensure that the data is resident in memory and a page fault
    00044     will not occur. If a page fault would occur, then the move is truncated.
    00045
    00046 Arguments:
    00047
    00048     Destination  - Supplies a pointer to destination of the move operation.
    00049
    00050     Source - Supplies a pointer to the source of the move operation.
    00051
    00052     Length - Supplies the length of the move operation.
    00053
    00054 Return Value:
    00055
    00056     The actual length of the move is returned as the fucntion value.
    00057
    00058 --*/
    00059
    00060 {
    00061
    00062     PVOID Address1;
    00063     PVOID Address2;
    00064     ULONG ActualLength;
    00065     ULONG_PTR Opaque;
    00066
    00067     //
    00068     // If the length is greater than the size of the message buffer, then
    00069     // reduce the length to the size of the message buffer.
    00070     //
    00071
    00072     if (Length > KDP_MESSAGE_BUFFER_SIZE) {
    00073         Length = KDP_MESSAGE_BUFFER_SIZE;
    00074     }
    00075
    00076     //
    00077     // Move the source information to the destination address.
    00078     //
    00079
    00080     ActualLength = Length;
    00081
    00082     while (((ULONG_PTR)Source & 3) && (Length > 0)) {
    00083
    00084     //
    00085     // Check to determine if the move will succeed before actually performing
    00086     // the operation.
    00087     //
    00088
    00089         Address1 = MmDbgWriteCheck((PVOID)Destination, &Opaque);
    00090         Address2 = MmDbgReadCheck((PVOID)Source);
    00091         if ((Address1 == NULL) || (Address2 == NULL)) {
    00092             break;
    00093         }
    00094         *(PCHAR)Address1 = *(PCHAR)Address2;
    00095         MmDbgReleaseAddress((PVOID)Destination, Opaque);
    00096         Destination += 1;
    00097         Source += 1;
    00098         Length -= 1;
    00099     }
    00100
    00101     while (Length > 3) {
    00102
    00103     //
    00104     // Check to determine if the move will succeed before actually performing
    00105     // the operation.
    00106     //
    00107
    00108         Address1 = MmDbgWriteCheck((PVOID)Destination, &Opaque);
    00109         Address2 = MmDbgReadCheck((PVOID)Source);
    00110         if ((Address1 == NULL) || (Address2 == NULL)) {
    00111             break;
    00112         }
    00113         *(ULONG UNALIGNED *)Address1 = *(PULONG)Address2;
    00114         MmDbgReleaseAddress((PVOID)Destination, Opaque);
    00115         Destination += 4;
    00116         Source += 4;
    00117         Length -= 4;
    00118
    00119     }
    00120
    00121     while (Length > 0) {
    00122
    00123     //
    00124     // Check to determine if the move will succeed before actually performing
    00125     // the operation.
    00126     //
    00127
    00128         Address1 = MmDbgWriteCheck((PVOID)Destination, &Opaque);
    00129         Address2 = MmDbgReadCheck((PVOID)Source);
    00130         if ((Address1 == NULL) || (Address2 == NULL)) {
    00131             break;
    00132         }
    00133         *(PCHAR)Address1 = *(PCHAR)Address2;
    00134         MmDbgReleaseAddress((PVOID)Destination, Opaque);
    00135         Destination += 1;
    00136         Source += 1;
    00137         Length -= 1;
    00138     }
    00139
    00140     //
    00141     // Flush the instruction cache in case the write was into the instruction
    00142     // stream.
    00143     //
    00144
    00145     KeSweepCurrentIcache();
    00146     return ActualLength - Length;
    00147 }
    00148
    00149 VOID
    00150 KdpQuickMoveMemory (
    00151     IN PCHAR Destination,
    00152     IN PCHAR Source,
    00153     IN ULONG Length
    00154     )
    00155
    00156 /*++
    00157
    00158 Routine Description:
    00159
    00160     This routine does the exact same thing as RtlMoveMemory, BUT it is
    00161     private to the debugger.  This allows folks to set breakpoints and
    00162     watch points in RtlMoveMemory without risk of recursive debugger
    00163     entry and the accompanying hang.
    00164
    00165     N.B.  UNLIKE KdpMoveMemory, this routine does NOT check for accessability
    00166       and may fault!  Use it ONLY in the debugger and ONLY where you
    00167       could use RtlMoveMemory.
    00168
    00169 Arguments:
    00170
    00171     Destination  - Supplies a pointer to destination of the move operation.
    00172
    00173     Source - Supplies a pointer to the source of the move operation.
    00174
    00175     Length - Supplies the length of the move operation.
    00176
    00177 Return Value:
    00178
    00179     None.
    00180
    00181 --*/
    00182 {
    00183     while (Length > 0) {
    00184         *Destination = *Source;
    00185         Destination++;
    00186         Source++;
    00187         Length--;
    00188     }
    00189 }