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 28 of file ke/i386/callback.c.

References ASSERT, CHAR, EXCEPTION_EXECUTE_HANDLER, KeGdiFlushUserBatch, KeGetCurrentThread, KiCallUserMode(), KiGetUserModeStackAddress(), NTSTATUS(), ProbeForWrite(), Status, UserMode, and ValueBuffer.

00038 : 00039 00040 This function call out from kernel mode to a user mode function. 00041 00042 Arguments: 00043 00044 ApiNumber - Supplies the API number. 00045 00046 InputBuffer - Supplies a pointer to a structure that is copied 00047 to the user stack. 00048 00049 InputLength - Supplies the length of the input structure. 00050 00051 Outputbuffer - Supplies a pointer to a variable that receives 00052 the address of the output buffer. 00053 00054 Outputlength - Supplies a pointer to a variable that receives 00055 the length of the output buffer. 00056 00057 Return Value: 00058 00059 If the callout cannot be executed, then an error status is 00060 returned. Otherwise, the status returned by the callback function 00061 is returned. 00062 00063 --*/ 00064 00065 { 00066 00067 ULONG Length; 00068 ULONG NewStack; 00069 ULONG OldStack; 00070 NTSTATUS Status; 00071 PULONG UserStack; 00072 PVOID ValueBuffer; 00073 ULONG ValueLength; 00074 PEXCEPTION_REGISTRATION_RECORD ExceptionList; 00075 PTEB Teb; 00076 00077 ASSERT(KeGetPreviousMode() == UserMode); 00078 00079 // 00080 // Get the user mode stack pointer and attempt to copy input buffer 00081 // to the user stack. 00082 // 00083 00084 UserStack = KiGetUserModeStackAddress(); 00085 OldStack = *UserStack; 00086 try { 00087 00088 // 00089 // Compute new user mode stack address, probe for writability, 00090 // and copy the input buffer to the user stack. 00091 // 00092 00093 Length = (InputLength + sizeof(CHAR) - 1) & ~(sizeof(CHAR) - 1); 00094 NewStack = OldStack - Length; 00095 ProbeForWrite((PCHAR)(NewStack - 16), Length + 16, sizeof(CHAR)); 00096 RtlCopyMemory((PVOID)NewStack, InputBuffer, Length); 00097 00098 // 00099 // Push arguments onto user stack. 00100 // 00101 00102 *(PULONG)(NewStack - 4) = (ULONG)InputLength; 00103 *(PULONG)(NewStack - 8) = (ULONG)NewStack; 00104 *(PULONG)(NewStack - 12) = ApiNumber; 00105 *(PULONG)(NewStack - 16) = 0; 00106 NewStack -= 16; 00107 00108 // 00109 // Save the exception list in case another handler is defined during 00110 // the callout. 00111 // 00112 00113 Teb = (PTEB)KeGetCurrentThread()->Teb; 00114 ExceptionList = Teb->NtTib.ExceptionList; 00115 00116 // 00117 // Call user mode. 00118 // 00119 00120 *UserStack = NewStack; 00121 Status = KiCallUserMode(OutputBuffer, OutputLength); 00122 00123 // 00124 // Restore exception list. 00125 // 00126 00127 Teb->NtTib.ExceptionList = ExceptionList; 00128 00129 // 00130 // If an exception occurs during the probe of the user stack, then 00131 // always handle the exception and return the exception code as the 00132 // status value. 00133 // 00134 00135 } except (EXCEPTION_EXECUTE_HANDLER) { 00136 return GetExceptionCode(); 00137 } 00138 00139 // 00140 // When returning from user mode, any drawing done to the GDI TEB 00141 // batch must be flushed. 00142 // 00143 00144 if (Teb->GdiBatchCount > 0) { 00145 00146 // 00147 // call GDI batch flush routine 00148 // 00149 00150 *UserStack -= 256; 00151 KeGdiFlushUserBatch(); 00152 } 00153 00154 *UserStack = OldStack; 00155 return Status; 00156 }

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

Definition at line 159 of file ke/i386/callback.c.

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

00169 : 00170 00171 This function calls a W32 function. 00172 00173 Arguments: 00174 00175 ApiNumber - Supplies the API number. 00176 00177 InputBuffer - Supplies a pointer to a structure that is copied to 00178 the user stack. 00179 00180 InputLength - Supplies the length of the input structure. 00181 00182 Outputbuffer - Supplies a pointer to a variable that recevies the 00183 output buffer address. 00184 00185 Outputlength - Supplies a pointer to a variable that recevies the 00186 output buffer length. 00187 00188 Return Value: 00189 00190 TBS. 00191 00192 --*/ 00193 00194 { 00195 00196 PVOID ValueBuffer; 00197 ULONG ValueLength; 00198 NTSTATUS Status; 00199 00200 ASSERT(KeGetPreviousMode() == UserMode); 00201 00202 // 00203 // If the current thread is not a GUI thread, then fail the service 00204 // since the thread does not have a large stack. 00205 // 00206 00207 if (KeGetCurrentThread()->Win32Thread == (PVOID)&KeServiceDescriptorTable[0]) { 00208 return STATUS_NOT_IMPLEMENTED; 00209 } 00210 00211 // 00212 // Probe the output buffer address and length for writeability. 00213 // 00214 00215 try { 00216 ProbeForWriteUlong((PULONG)OutputBuffer); 00217 ProbeForWriteUlong(OutputLength); 00218 00219 // 00220 // If an exception occurs during the probe of the output buffer or 00221 // length, then always handle the exception and return the exception 00222 // code as the status value. 00223 // 00224 00225 } except(EXCEPTION_EXECUTE_HANDLER) { 00226 return GetExceptionCode(); 00227 } 00228 00229 // 00230 // Call out to user mode specifying the input buffer and API number. 00231 // 00232 00233 Status = KeUserModeCallback(ApiNumber, 00234 InputBuffer, 00235 InputLength, 00236 &ValueBuffer, 00237 &ValueLength); 00238 00239 // 00240 // If the callout is successful, then the output buffer address and 00241 // length. 00242 // 00243 00244 if (NT_SUCCESS(Status)) { 00245 try { 00246 *OutputBuffer = ValueBuffer; 00247 *OutputLength = ValueLength; 00248 00249 } except(EXCEPTION_EXECUTE_HANDLER) { 00250 } 00251 } 00252 00253 return Status; 00254 } }


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