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 ULONG_PTR 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
00082
while (((ULONG_PTR)Source & 3) && (Length > 0)) {
00083
00084
00085
00086
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
00105
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
00125
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
00142
00143
00144
00145 KeSweepCurrentIcache();
00146
return ActualLength - Length;
00147 }