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 }

Generated on Sat May 15 19:40:34 2004 for test by doxygen 1.3.7