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
00026
00027
#include "ki.h"
00028
00029
NTSTATUS
00030 KeUserModeCallback (
00031 IN ULONG ApiNumber,
00032 IN PVOID InputBuffer,
00033 IN ULONG InputLength,
00034 OUT PVOID *OutputBuffer,
00035 IN PULONG OutputLength
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 {
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
00082
00083
00084
00085 TrapFrame =
KeGetCurrentThread()->TrapFrame;
00086 OldStack = TrapFrame->IntSp;
00087 OldStIFS = TrapFrame->StIFS;
00088
00089
try {
00090
00091
00092
00093
00094
00095
00096
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
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
00129
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
00148
00149
00150
00151
00152
00153 UserRnats2 = *(PULONGLONG)BottomBound & Mask;
00154 *(PULONGLONG)BottomBound = UserRnats1 | UserRnats2;
00155 TrapFrame->RsRNAT = CurrentRNAT;
00156
00157 }
else {
00158
00159
00160
00161
00162
00163
00164
00165 UserRnats2 = CurrentRNAT & Mask;
00166 TrapFrame->RsRNAT = UserRnats1 | UserRnats2;
00167
00168 }
00169
00170 TrapFrame->RsBSPSTORE = TrapFrame->RsBSP;
00171 }
00172 }
00173
00174
00175
00176
00177
00178
00179
00180 } except (
EXCEPTION_EXECUTE_HANDLER) {
00181
return GetExceptionCode();
00182 }
00183
00184
00185
00186
00187
00188 TrapFrame->StIFS = 0xC000000000000000i64;
00189 TrapFrame->IntSp = NewStack;
00190
Status =
KiCallUserMode(OutputBuffer, OutputLength);
00191
00192
00193
00194
00195
00196
00197
if (((PTEB)
KeGetCurrentThread()->Teb)->GdiBatchCount > 0) {
00198
00199
00200
00201
00202
00203
KeGdiFlushUserBatch();
00204 }
00205
00206 TrapFrame->IntSp = OldStack;
00207 TrapFrame->StIFS = OldStIFS;
00208
return Status;
00209
00210 }
00211
00212
NTSTATUS
00213 NtW32Call (
00214 IN ULONG ApiNumber,
00215 IN PVOID InputBuffer,
00216 IN ULONG InputLength,
00217 OUT PVOID *OutputBuffer,
00218 OUT PULONG OutputLength
00219 )
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 {
00251
00252 PVOID
ValueBuffer;
00253 ULONG ValueLength;
00254
NTSTATUS Status;
00255
00256
ASSERT(KeGetPreviousMode() ==
UserMode);
00257
00258
00259
00260
00261
00262
00263
if (
KeGetCurrentThread()->Win32Thread == (PVOID)&
KeServiceDescriptorTable[0]) {
00264
return STATUS_NOT_IMPLEMENTED;
00265 }
00266
00267
00268
00269
00270
00271
try {
00272
ProbeForWriteUlong((PULONG)OutputBuffer);
00273
ProbeForWriteUlong(OutputLength);
00274
00275
00276
00277
00278
00279
00280
00281 } except(
EXCEPTION_EXECUTE_HANDLER) {
00282
return GetExceptionCode();
00283 }
00284
00285
00286
00287
00288
00289
Status =
KeUserModeCallback(ApiNumber,
00290 InputBuffer,
00291 InputLength,
00292 &
ValueBuffer,
00293 &ValueLength);
00294
00295
00296
00297
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 }