Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

flushbuf.c File Reference

#include "mi.h"

Go to the source code of this file.

Functions

NTSTATUS NtFlushWriteBuffer (VOID)
ULONG MiFlushRangeFilter (IN PEXCEPTION_POINTERS ExceptionPointers, IN PVOID *BaseAddress, IN PULONG Length, IN PBOOLEAN Retry)
NTSTATUS NtFlushInstructionCache (IN HANDLE ProcessHandle, IN PVOID BaseAddress OPTIONAL, IN ULONG Length)


Function Documentation

ULONG MiFlushRangeFilter IN PEXCEPTION_POINTERS  ExceptionPointers,
IN PVOID *  BaseAddress,
IN PULONG  Length,
IN PBOOLEAN  Retry
 

Definition at line 60 of file flushbuf.c.

References EXCEPTION_EXECUTE_HANDLER, ROUND_TO_PAGES, and TRUE.

Referenced by NtFlushInstructionCache().

00069 : 00070 00071 This is the exception handler used by NtFlushInstructionCache to protect 00072 against bad virtual addresses passed to KeSweepIcacheRange. If an 00073 access violation occurs, this routine causes NtFlushInstructionCache to 00074 restart the sweep at the page following the failing page. 00075 00076 Arguments: 00077 00078 ExceptionPointers - Supplies exception information. 00079 00080 BaseAddress - Supplies a pointer to address the base of the region 00081 being flushed. If the failing address is not in the last page 00082 of the region, this routine updates BaseAddress to point to the 00083 next page of the region. 00084 00085 Length - Supplies a pointer the length of the region being flushed. 00086 If the failing address is not in the last page of the region, 00087 this routine updates Length to reflect restarting the flush at 00088 the next page of the region. 00089 00090 Retry - Supplies a pointer to a boolean that the caller has initialized 00091 to FALSE. This routine sets this boolean to TRUE if an access 00092 violation occurs in a page before the last page of the flush region. 00093 00094 Return Value: 00095 00096 EXCEPTION_EXECUTE_HANDLER. 00097 00098 --*/ 00099 00100 { 00101 PEXCEPTION_RECORD ExceptionRecord; 00102 ULONG_PTR BadVa; 00103 ULONG_PTR NextVa; 00104 ULONG_PTR EndVa; 00105 00106 ExceptionRecord = ExceptionPointers->ExceptionRecord; 00107 00108 // 00109 // If the exception was an access violation, skip the current page of the 00110 // region and move to the next page. 00111 // 00112 00113 if ( ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION ) { 00114 00115 // 00116 // Get the failing address, calculate the base address of the next page, 00117 // and calculate the address at the end of the region. 00118 // 00119 00120 BadVa = ExceptionRecord->ExceptionInformation[1]; 00121 NextVa = ROUND_TO_PAGES( BadVa + 1 ); 00122 EndVa = *(PULONG_PTR)BaseAddress + *Length; 00123 00124 // 00125 // If the next page didn't wrap, and the next page is below the end of 00126 // the region, update Length and BaseAddress appropriately and set Retry 00127 // to TRUE to indicate to NtFlushInstructionCache that it should call 00128 // KeSweepIcacheRange again. 00129 // 00130 00131 if ( (NextVa > BadVa) && (NextVa < EndVa) ) { 00132 *Length = (ULONG) (EndVa - NextVa); 00133 *BaseAddress = (PVOID)NextVa; 00134 *Retry = TRUE; 00135 } 00136 } 00137 00138 return EXCEPTION_EXECUTE_HANDLER; 00139 }

NTSTATUS NtFlushInstructionCache IN HANDLE  ProcessHandle,
IN PVOID BaseAddress  OPTIONAL,
IN ULONG  Length
 

Definition at line 142 of file flushbuf.c.

References EXCEPTION_EXECUTE_HANDLER, FALSE, KeAttachProcess(), KeDetachProcess(), KernelMode, KeSweepIcache(), KeSweepIcacheRange(), KPROCESSOR_MODE, MiFlushRangeFilter(), NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PAGED_CODE, ProbeForRead, PsProcessType, and Status.

Referenced by LdrpSetProtection(), and LdrpSnapIAT().

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 // If the base address is not specified, or the base address is specified 00187 // and the length is not zero, then flush the specified instruction cache 00188 // range. 00189 // 00190 00191 if ((ARGUMENT_PRESENT(BaseAddress) == FALSE) || (Length != 0)) { 00192 00193 // 00194 // If previous mode is user and the range specified falls in kernel 00195 // address space, return an error. 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 // If the specified process is not the current process, then 00209 // the process must be attached to during the flush. 00210 // 00211 00212 if (ProcessHandle != NtCurrentProcess()) { 00213 00214 // 00215 // Reference the specified process checking for PROCESS_VM_WRITE 00216 // access. 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 // Attach to the process. 00232 // 00233 00234 KeAttachProcess(&Process->Pcb); 00235 } 00236 00237 // 00238 // If the base address is not specified, sweep the entire instruction 00239 // cache. If the base address is specified, flush the specified range. 00240 // 00241 00242 if (ARGUMENT_PRESENT(BaseAddress) == FALSE) { 00243 KeSweepIcache(FALSE); 00244 00245 } else { 00246 00247 // 00248 // Parts of the specified range may be invalid. An exception 00249 // handler is used to skip over those parts. Before calling 00250 // KeSweepIcacheRange, we set Retry to FALSE. If an access 00251 // violation occurs in KeSweepIcacheRange, the MiFlushRangeFilter 00252 // exception filter is called. It updates RangeBase and 00253 // RangeLength to skip over the failing page, and sets Retry to 00254 // TRUE. As long as Retry is TRUE, we continue to call 00255 // KeSweepIcacheRange. 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 // If the specified process is not the current process, then 00278 // detach from it and dereference it. 00279 // 00280 00281 if (ProcessHandle != NtCurrentProcess()) { 00282 KeDetachProcess(); 00283 ObDereferenceObject(Process); 00284 } 00285 } 00286 00287 return STATUS_SUCCESS; 00288 }

NTSTATUS NtFlushWriteBuffer VOID   ) 
 

Definition at line 32 of file flushbuf.c.

References KeFlushWriteBuffer(), and PAGED_CODE.

00038 : 00039 00040 This function flushes the write buffer on the current processor. 00041 00042 Arguments: 00043 00044 None. 00045 00046 Return Value: 00047 00048 STATUS_SUCCESS. 00049 00050 --*/ 00051 00052 { 00053 PAGED_CODE(); 00054 00055 KeFlushWriteBuffer(); 00056 return STATUS_SUCCESS; 00057 }


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