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 }