00039                    :
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     
00069     
00070     
00071 
00072     
if (Length > 
KDP_MESSAGE_BUFFER_SIZE) {
00073         Length = 
KDP_MESSAGE_BUFFER_SIZE;
00074     }
00075 
00076     
00077     
00078     
00079 
00080     ActualLength = Length;
00081     Address1 = 
NULL;
00082 
00083     
while (((ULONG_PTR)Source & 3) && (Length > 0)) {
00084 
00085     
00086     
00087     
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     
00113     
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     
00140     
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     
00164     
00165     
00166 
00167     KeSweepCurrentIcache();
00168     
return ActualLength - Length;
00169 }