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     HARDWARE_PTE 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     Address1 = NULL;
    00082
    00083     while (((ULONG_PTR)Source & 3) && (Length > 0)) {
    00084
    00085     //
    00086     // Check to determine if the move will succeed before actually performing
    00087     // the operation.
    00088     //
    00089
    00090         Address1 = MmDbgWriteCheck((PVOID)Destination, &Opaque);
    00091         Address2 = MmDbgReadCheck((PVOID)Source);
    00092         if ((Address1 == NULL) || (Address2 == NULL)) {
    00093             break;
    00094         }
    00095         *(PCHAR)Address1 = *(PCHAR)Address2;
    00096         MmDbgReleaseAddress(Address1, &Opaque);
    00097         Address1 = NULL;
    00098
    00099         Destination += 1;
    00100         Source += 1;
    00101         Length -= 1;
    00102     }
    00103
    00104     if (Address1 != NULL) {
    00105         MmDbgReleaseAddress(Address1, &Opaque);
    00106         Address1 = NULL;
    00107     }
    00108
    00109     while (Length > 3) {
    00110
    00111     //
    00112     // Check to determine if the move will succeed before actually performing
    00113     // the operation.
    00114     //
    00115
    00116         Address1 = MmDbgWriteCheck((PVOID)Destination, &Opaque);
    00117         Address2 = MmDbgReadCheck((PVOID)Source);
    00118         if ((Address1 == NULL) || (Address2 == NULL)) {
    00119             break;
    00120         }
    00121         *(ULONG UNALIGNED *)Address1 = *(PULONG)Address2;
    00122         MmDbgReleaseAddress(Address1, &Opaque);
    00123         Address1 = NULL;
    00124
    00125         Destination += 4;
    00126         Source += 4;
    00127         Length -= 4;
    00128
    00129     }
    00130
    00131     if (Address1 != NULL) {
    00132         MmDbgReleaseAddress(Address1, &Opaque);
    00133         Address1 = NULL;
    00134     }
    00135
    00136     while (Length > 0) {
    00137
    00138     //
    00139     // Check to determine if the move will succeed before actually performing
    00140     // the operation.
    00141     //
    00142
    00143         Address1 = MmDbgWriteCheck((PVOID)Destination, &Opaque);
    00144         Address2 = MmDbgReadCheck((PVOID)Source);
    00145         if ((Address1 == NULL) || (Address2 == NULL)) {
    00146             break;
    00147         }
    00148         *(PCHAR)Address1 = *(PCHAR)Address2;
    00149         MmDbgReleaseAddress(Address1, &Opaque);
    00150         Address1 = NULL;
    00151
    00152         Destination += 1;
    00153         Source += 1;
    00154         Length -= 1;
    00155     }
    00156
    00157     if (Address1 != NULL) {
    00158         MmDbgReleaseAddress(Address1, &Opaque);
    00159         Address1 = NULL;
    00160     }
    00161
    00162     //
    00163     // Flush the instruction cache in case the write was into the instruction
    00164     // stream.
    00165     //
    00166
    00167     KeSweepCurrentIcache();
    00168     return ActualLength - Length;
    00169 }
    00170
    00171 VOID
    00172 KdpQuickMoveMemory (
    00173     IN PCHAR Destination,
    00174     IN PCHAR Source,
    00175     IN ULONG Length
    00176     )
    00177
    00178 /*++
    00179
    00180 Routine Description:
    00181
    00182     This routine does the exact same thing as RtlMoveMemory, BUT it is
    00183     private to the debugger.  This allows folks to set breakpoints and
    00184     watch points in RtlMoveMemory without risk of recursive debugger
    00185     entry and the accompanying hang.
    00186
    00187     N.B.  UNLIKE KdpMoveMemory, this routine does NOT check for accessability
    00188       and may fault!  Use it ONLY in the debugger and ONLY where you
    00189       could use RtlMoveMemory.
    00190
    00191 Arguments:
    00192
    00193     Destination  - Supplies a pointer to destination of the move operation.
    00194
    00195     Source - Supplies a pointer to the source of the move operation.
    00196
    00197     Length - Supplies the length of the move operation.
    00198
    00199 Return Value:
    00200
    00201     None.
    00202
    00203 --*/
    00204 {
    00205     while (Length > 0) {
    00206         *Destination = *Source;
    00207         Destination++;
    00208         Source++;
    00209         Length--;
    00210     }
    00211 }