00150 :
00151
00152 This function flushes
the instruction cache
for the specified process.
00153
00154 Arguments:
00155
00156 ProcessHandle - Supplies a handle to
the process in which
the instruction
00157 cache
is to be flushed. Must have PROCESS_VM_WRITE access to
the
00158 specified process.
00159
00160 BaseAddress - Supplies an optional pointer to base of
the region that
00161
is flushed.
00162
00163 Length - Supplies
the length of
the region that
is flushed
if the base
00164 address
is specified.
00165
00166 Return Value:
00167
00168 STATUS_SUCCESS.
00169
00170 --*/
00171
00172 {
00173
00174
KPROCESSOR_MODE PreviousMode;
00175
PEPROCESS Process;
00176
NTSTATUS Status;
00177 BOOLEAN Retry;
00178 PVOID RangeBase;
00179 ULONG RangeLength;
00180
00181
PAGED_CODE();
00182
00183 PreviousMode = KeGetPreviousMode();
00184
00185
00186
00187
00188
00189
00190
00191
if ((ARGUMENT_PRESENT(BaseAddress) ==
FALSE) || (Length != 0)) {
00192
00193
00194
00195
00196
00197
00198
if ((ARGUMENT_PRESENT(BaseAddress) !=
FALSE) &&
00199 (PreviousMode !=
KernelMode)) {
00200
try {
00201
ProbeForRead(BaseAddress, Length,
sizeof(UCHAR));
00202 } except(EXCEPTION_EXECUTE_HANDLER) {
00203
return GetExceptionCode();
00204 }
00205 }
00206
00207
00208
00209
00210
00211
00212
if (ProcessHandle != NtCurrentProcess()) {
00213
00214
00215
00216
00217
00218
00219
Status =
ObReferenceObjectByHandle(ProcessHandle,
00220 PROCESS_VM_WRITE,
00221 PsProcessType,
00222 PreviousMode,
00223 (PVOID *)&Process,
00224 NULL);
00225
00226
if (!
NT_SUCCESS(Status)) {
00227
return Status;
00228 }
00229
00230
00231
00232
00233
00234
KeAttachProcess(&Process->
Pcb);
00235 }
00236
00237
00238
00239
00240
00241
00242
if (ARGUMENT_PRESENT(BaseAddress) ==
FALSE) {
00243
KeSweepIcache(FALSE);
00244
00245 }
else {
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 RangeBase = BaseAddress;
00259 RangeLength = Length;
00260
00261
do {
00262 Retry =
FALSE;
00263
try {
00264
KeSweepIcacheRange(FALSE, RangeBase, RangeLength);
00265 } except(
MiFlushRangeFilter(GetExceptionInformation(),
00266 &RangeBase,
00267 &RangeLength,
00268 &Retry)) {
00269
if (GetExceptionCode() != STATUS_ACCESS_VIOLATION) {
00270
Status = GetExceptionCode();
00271 }
00272 }
00273 }
while (Retry !=
FALSE);
00274 }
00275
00276
00277
00278
00279
00280
00281
if (ProcessHandle != NtCurrentProcess()) {
00282
KeDetachProcess();
00283
ObDereferenceObject(Process);
00284 }
00285 }
00286
00287
return STATUS_SUCCESS;
00288 }