00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
#include "ki.h"
00026 
00027 
NTSTATUS
00028 KeUserModeCallback (
00029     IN ULONG ApiNumber,
00030     IN PVOID InputBuffer,
00031     IN ULONG InputLength,
00032     OUT PVOID *OutputBuffer,
00033     IN PULONG OutputLength
00034     )
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
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     
00081     
00082     
00083 
00084     UserStack = 
KiGetUserModeStackAddress();
00085     OldStack = *UserStack;
00086     
try {
00087 
00088         
00089         
00090         
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         
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         
00110         
00111         
00112 
00113         Teb = (PTEB)
KeGetCurrentThread()->Teb;
00114         ExceptionList = Teb->NtTib.ExceptionList;
00115 
00116         
00117         
00118         
00119 
00120         *UserStack = NewStack;
00121         
Status = 
KiCallUserMode(OutputBuffer, OutputLength);
00122 
00123         
00124         
00125         
00126 
00127         Teb->NtTib.ExceptionList = ExceptionList;
00128 
00129     
00130     
00131     
00132     
00133     
00134 
00135     } except (
EXCEPTION_EXECUTE_HANDLER) {
00136         
return GetExceptionCode();
00137     }
00138 
00139     
00140     
00141     
00142     
00143 
00144     
if (Teb->GdiBatchCount > 0) {
00145 
00146         
00147         
00148         
00149 
00150         *UserStack -= 256;
00151         
KeGdiFlushUserBatch();
00152     }
00153 
00154     *UserStack = OldStack;
00155     
return Status;
00156 }
00157 
00158 
NTSTATUS
00159 NtW32Call (
00160     IN ULONG ApiNumber,
00161     IN PVOID InputBuffer,
00162     IN ULONG InputLength,
00163     OUT PVOID *OutputBuffer,
00164     OUT PULONG OutputLength
00165     )
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 {
00195 
00196     PVOID 
ValueBuffer;
00197     ULONG ValueLength;
00198     
NTSTATUS Status;
00199 
00200     
ASSERT(KeGetPreviousMode() == 
UserMode);
00201 
00202     
00203     
00204     
00205     
00206 
00207     
if (
KeGetCurrentThread()->Win32Thread == (PVOID)&
KeServiceDescriptorTable[0]) {
00208         
return STATUS_NOT_IMPLEMENTED;
00209     }
00210 
00211     
00212     
00213     
00214 
00215     
try {
00216         
ProbeForWriteUlong((PULONG)OutputBuffer);
00217         
ProbeForWriteUlong(OutputLength);
00218 
00219     
00220     
00221     
00222     
00223     
00224 
00225     } except(
EXCEPTION_EXECUTE_HANDLER) {
00226         
return GetExceptionCode();
00227     }
00228 
00229     
00230     
00231     
00232 
00233     
Status = 
KeUserModeCallback(ApiNumber,
00234                                 InputBuffer,
00235                                 InputLength,
00236                                 &
ValueBuffer,
00237                                 &ValueLength);
00238 
00239     
00240     
00241     
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 }