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

callback.c File Reference

#include "ki.h"

Go to the source code of this file.

Functions

NTSTATUS KeUserModeCallback (IN ULONG ApiNumber, IN PVOID InputBuffer, IN ULONG InputLength, OUT PVOID *OutputBuffer, IN PULONG OutputLength)
NTSTATUS NtW32Call (IN ULONG ApiNumber, IN PVOID InputBuffer, IN ULONG InputLength, OUT PVOID *OutputBuffer, OUT PULONG OutputLength)


Function Documentation

NTSTATUS KeUserModeCallback IN ULONG  ApiNumber,
IN PVOID  InputBuffer,
IN ULONG  InputLength,
OUT PVOID *  OutputBuffer,
IN PULONG  OutputLength
 

Definition at line 30 of file ke/ia64/callback.c.

References ASSERT, EXCEPTION_EXECUTE_HANDLER, KeGdiFlushUserBatch, KeGetCurrentThread, KiCallUserMode(), NTSTATUS(), NULL, ProbeForWrite(), PsGetCurrentProcess, SHORT, Status, UserMode, and USHORT.

00040 : 00041 00042 This function call out from kernel mode to a user mode function. 00043 00044 Arguments: 00045 00046 ApiNumber - Supplies the API number. 00047 00048 InputBuffer - Supplies a pointer to a structure that is copied 00049 to the user stack. 00050 00051 InputLength - Supplies the length of the input structure. 00052 00053 Outputbuffer - Supplies a pointer to a variable that receives 00054 the address of the output buffer. 00055 00056 Outputlength - Supplies a pointer to a variable that receives 00057 the length of the output buffer. 00058 00059 Return Value: 00060 00061 If the callout cannot be executed, then an error status is 00062 returned. Otherwise, the status returned by the callback function 00063 is returned. 00064 00065 --*/ 00066 00067 { 00068 PUCALLOUT_FRAME CalloutFrame; 00069 ULONGLONG OldStack; 00070 ULONGLONG NewStack; 00071 ULONGLONG OldStIFS; 00072 PKTRAP_FRAME TrapFrame; 00073 NTSTATUS Status; 00074 ULONG Length; 00075 SHORT BsFrameSize; 00076 USHORT TearPointOffset; 00077 00078 ASSERT(KeGetPreviousMode() == UserMode); 00079 00080 // 00081 // Get the user mode stack pointer and attempt to copy input buffer 00082 // to the user stack. 00083 // 00084 00085 TrapFrame = KeGetCurrentThread()->TrapFrame; 00086 OldStack = TrapFrame->IntSp; 00087 OldStIFS = TrapFrame->StIFS; 00088 00089 try { 00090 00091 // 00092 // Compute new user mode stack address, probe for writability, 00093 // and copy the input buffer to the user stack. 00094 // 00095 // N.B. EM requires stacks to be 16-byte aligned, therefore 00096 // the input length must be rounded up to a 16-byte boundary. 00097 // 00098 00099 Length = (InputLength + 16 - 1 + sizeof(UCALLOUT_FRAME) + STACK_SCRATCH_AREA) & ~(16 - 1); 00100 NewStack = OldStack - Length; 00101 CalloutFrame = (PUCALLOUT_FRAME)(NewStack + STACK_SCRATCH_AREA); 00102 ProbeForWrite((PVOID)NewStack, Length, sizeof(QUAD)); 00103 RtlCopyMemory(CalloutFrame + 1, InputBuffer, InputLength); 00104 00105 // 00106 // Fill in the callout arguments. 00107 // 00108 00109 CalloutFrame->Buffer = (PVOID)(CalloutFrame + 1); 00110 CalloutFrame->Length = InputLength; 00111 CalloutFrame->ApiNumber = ApiNumber; 00112 CalloutFrame->IntSp = OldStack; 00113 CalloutFrame->RsPFS = TrapFrame->StIFS; 00114 CalloutFrame->BrRp = TrapFrame->BrRp; 00115 00116 if (PsGetCurrentProcess()->DebugPort != NULL) { 00117 KiFlushRse(); 00118 BsFrameSize = (SHORT)(TrapFrame->RsBSP - TrapFrame->RsBSPSTORE); 00119 if (BsFrameSize) { 00120 00121 ULONGLONG TopBound, BottomBound; 00122 ULONGLONG UserRnats1, UserRnats2; 00123 ULONGLONG Mask; 00124 ULONGLONG CurrentRNAT = 0; 00125 SHORT RNatSaveIndex; 00126 00127 // 00128 // Copy the dirty stacked registers back into the 00129 // user backing store 00130 // 00131 00132 TearPointOffset = (USHORT) TrapFrame->RsBSPSTORE & 0x1F8; 00133 RtlCopyMemory((PVOID)(TrapFrame->RsBSPSTORE), 00134 (PVOID)(PCR->InitialBStore + TearPointOffset), 00135 BsFrameSize); 00136 00137 TopBound = TrapFrame->RsBSP | RNAT_ALIGNMENT; 00138 BottomBound = TrapFrame->RsBSPSTORE | RNAT_ALIGNMENT; 00139 00140 RNatSaveIndex = TearPointOffset >> 3; 00141 Mask = (((1ULL << (NAT_BITS_PER_RNAT_REG - RNatSaveIndex)) - 1) << RNatSaveIndex); 00142 UserRnats1 = TrapFrame->RsRNAT & ((1ULL << RNatSaveIndex) - 1); 00143 00144 if (TopBound > BottomBound) { 00145 00146 // 00147 // user dirty stacked GR span across at least one RNAT 00148 // boundary; need to deposit the valid RNAT bits from 00149 // the trap frame into the kernel backing store. Also, 00150 // the RNAT field in the trap frame has to be updated. 00151 // 00152 00153 UserRnats2 = *(PULONGLONG)BottomBound & Mask; 00154 *(PULONGLONG)BottomBound = UserRnats1 | UserRnats2; 00155 TrapFrame->RsRNAT = CurrentRNAT; 00156 00157 } else { 00158 00159 // 00160 // user stacked register region does not span across an 00161 // RNAT boundary; combine the RNAT fields from both the 00162 // trap frame and the context frame. 00163 // 00164 00165 UserRnats2 = CurrentRNAT & Mask; 00166 TrapFrame->RsRNAT = UserRnats1 | UserRnats2; 00167 00168 } 00169 00170 TrapFrame->RsBSPSTORE = TrapFrame->RsBSP; 00171 } 00172 } 00173 00174 // 00175 // If an exception occurs during the probe of the user stack, then 00176 // always handle the exception and return the exception code as the 00177 // status value. 00178 // 00179 00180 } except (EXCEPTION_EXECUTE_HANDLER) { 00181 return GetExceptionCode(); 00182 } 00183 00184 // 00185 // Call user mode. 00186 // 00187 00188 TrapFrame->StIFS = 0xC000000000000000i64; 00189 TrapFrame->IntSp = NewStack; 00190 Status = KiCallUserMode(OutputBuffer, OutputLength); 00191 00192 // 00193 // When returning from user mode, any drawing done to the GDI TEB 00194 // batch must be flushed. 00195 // 00196 00197 if (((PTEB)KeGetCurrentThread()->Teb)->GdiBatchCount > 0) { 00198 00199 // 00200 // call GDI batch flush routine 00201 // 00202 00203 KeGdiFlushUserBatch(); 00204 } 00205 00206 TrapFrame->IntSp = OldStack; 00207 TrapFrame->StIFS = OldStIFS; 00208 return Status; 00209 00210 }

NTSTATUS NtW32Call IN ULONG  ApiNumber,
IN PVOID  InputBuffer,
IN ULONG  InputLength,
OUT PVOID *  OutputBuffer,
OUT PULONG  OutputLength
 

Definition at line 213 of file ke/ia64/callback.c.

References ASSERT, EXCEPTION_EXECUTE_HANDLER, KeGetCurrentThread, KeServiceDescriptorTable, KeUserModeCallback(), NT_SUCCESS, NTSTATUS(), ProbeForWriteUlong, Status, UserMode, and ValueBuffer.

00223 : 00224 00225 This function calls a W32 function. 00226 00227 N.B. ************** This is a temporary service ***************** 00228 00229 Arguments: 00230 00231 ApiNumber - Supplies the API number. 00232 00233 InputBuffer - Supplies a pointer to a structure that is copied to 00234 the user stack. 00235 00236 InputLength - Supplies the length of the input structure. 00237 00238 Outputbuffer - Supplies a pointer to a variable that recevies the 00239 output buffer address. 00240 00241 Outputlength - Supplies a pointer to a variable that recevies the 00242 output buffer length. 00243 00244 Return Value: 00245 00246 TBS. 00247 00248 --*/ 00249 00250 { 00251 00252 PVOID ValueBuffer; 00253 ULONG ValueLength; 00254 NTSTATUS Status; 00255 00256 ASSERT(KeGetPreviousMode() == UserMode); 00257 00258 // 00259 // If the current thread is not a GUI thread, then fail the service 00260 // since the thread does not have a large stack. 00261 // 00262 00263 if (KeGetCurrentThread()->Win32Thread == (PVOID)&KeServiceDescriptorTable[0]) { 00264 return STATUS_NOT_IMPLEMENTED; 00265 } 00266 00267 // 00268 // Probe the output buffer address and length for writeability. 00269 // 00270 00271 try { 00272 ProbeForWriteUlong((PULONG)OutputBuffer); 00273 ProbeForWriteUlong(OutputLength); 00274 00275 // 00276 // If an exception occurs during the probe of the output buffer or 00277 // length, then always handle the exception and return the exception 00278 // code as the status value. 00279 // 00280 00281 } except(EXCEPTION_EXECUTE_HANDLER) { 00282 return GetExceptionCode(); 00283 } 00284 00285 // 00286 // Call out to user mode specifying the input buffer and API number. 00287 // 00288 00289 Status = KeUserModeCallback(ApiNumber, 00290 InputBuffer, 00291 InputLength, 00292 &ValueBuffer, 00293 &ValueLength); 00294 00295 // 00296 // If the callout is successful, then the output buffer address and 00297 // length. 00298 // 00299 00300 if (NT_SUCCESS(Status)) { 00301 try { 00302 *OutputBuffer = ValueBuffer; 00303 *OutputLength = ValueLength; 00304 00305 } except(EXCEPTION_EXECUTE_HANDLER) { 00306 } 00307 } 00308 00309 return Status; 00310 } }


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