00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
#include "precomp.h"
00012
#pragma hdrstop
00013
00014 #define CALLBACKPROC 1
00015 #define SERVERSIDE 1
00016
00017
#include "callback.h"
00018
00019 #define SENDSIDE 1
00020
00021 #define CBBUFSIZE 512
00022
00023 #define PADSIZE (sizeof(ULONG_PTR) - 1)
00024
00025
00026
00027
00028 #define SMESSAGECALL(api) \
00029
LRESULT Sfn ## api( \
00030
PWND pwnd, \
00031
UINT msg, \
00032
WPARAM wParam, \
00033
LPARAM lParam, \
00034
ULONG_PTR xParam, \
00035
PROC xpfnProc, \
00036
DWORD dwSCMSFlags, \
00037
PSMS psms)
00038
00039 #define SETUP(api) \
00040
api ## MSG m; \
00041
api ## MSG *mp = &m; \
00042
BYTE Buffer[CBBUFSIZE]; \
00043
PCALLBACKSTATUS pcbs; \
00044
ULONG cbCBStatus; \
00045
ULONG_PTR retval; \
00046
NTSTATUS Status;
00047
00048 #define SETUPDC(api) \
00049
SETUP(api) \
00050
int iDC = 0; \
00051
HDC hdcUse; \
00052
HBITMAP hbmDCGray = NULL;
00053
00054
00055 #define SETUPPWND(api) \
00056
api ## MSG m; \
00057
api ## MSG *mp = &m; \
00058
BYTE Buffer[CBBUFSIZE]; \
00059
PCALLBACKSTATUS pcbs; \
00060
ULONG cbCBStatus; \
00061
ULONG_PTR retval; \
00062
NTSTATUS Status; \
00063
TL tlpwnd; \
00064
CALLBACKWND cbwin; \
00065
PCLIENTINFO pci = PtiCurrent()->pClientInfo; \
00066
PWND pwndClient = pwnd ? (PWND)((PBYTE)pwnd - pci->ulClientDelta) : NULL; \
00067
UserAssert(pci->ulClientDelta != 0);
00068
00069 #define CALC_SIZE_IN(cb, pstr) \
00070
cb = (pstr)->Length + sizeof(WCHAR); \
00071
if ((pstr)->bAnsi && !fAnsiReceiver) \
00072
cb *= sizeof(WCHAR);
00073
00074 #define CALC_SIZE_OUT(cb, pstr) \
00075
cb = (pstr)->MaximumLength + sizeof(WCHAR); \
00076
if ((pstr)->bAnsi && !fAnsiReceiver) \
00077
cb *= sizeof(WCHAR);
00078
00079
#ifdef FE_SB // CALC_SIZE_OUT_STRING()
00080
#define CALC_SIZE_OUT_STRING(cb, pstr) \
00081
cb = (pstr)->MaximumLength + sizeof(WCHAR); \
00082
if (!(PtiCurrent()->TIF_flags & TIF_ANSILENGTH)) { \
00083
if ((pstr)->bAnsi && !fAnsiReceiver) \
00084
cb *= sizeof(WCHAR); \
00085
}
00086
#endif // FE_SB
00087
00088
#ifdef FE_SB // CALC_SIZE_STRING_OUT()
00089
#define CALC_SIZE_STRING_OUT(cchText) \
00090
try { \
00091
(cchText) = CalcOutputStringSize(pcbs,(cchText),fAnsiSender,fAnsiReceiver); \
00092
} except (W32ExceptionHandler(FALSE, RIP_ERROR)) { \
00093
(cchText) = 0; \
00094
MSGERROR(); \
00095
}
00096
#endif // FE_SB
00097
00098 #define BEGINSEND(api) \
00099
mp = &m; \
00100
Buffer; \
00101
{
00102
00103 #define BEGINSENDCAPTURE(api, cCapturePointers, cCaptureBytes, fInput) \
00104
if (cCapturePointers) { \
00105
mp = AllocCallbackMessage(sizeof(m), \
00106
(cCapturePointers), \
00107
(cCaptureBytes), \
00108
Buffer, \
00109
fInput); \
00110
if (mp == NULL) \
00111
goto errorexitnofreemp; \
00112
} else { \
00113
m.CaptureBuf.cbCallback = sizeof(m); \
00114
m.CaptureBuf.cbCapture = 0; \
00115
m.CaptureBuf.cCapturedPointers = 0; \
00116
mp = &m; \
00117
} \
00118
{ \
00119
PTHREADINFO ptiCurrent = PtiCurrent(); \
00120
TL tlPool; \
00121
\
00122
if (mp != &m && (PVOID)mp != (PVOID)Buffer) \
00123
ThreadLockPool(ptiCurrent, mp, &tlPool);
00124
00125 #define BEGINSENDCAPTUREVOIDDC(api, cCapturePointers, cCaptureBytes, fInput) \
00126
hdcUse = CreateCompatiblePublicDC(hdc,&hbmDCGray); \
00127
if (hdcUse == (HDC)NULL) { \
00128
return; \
00129
} \
00130
BEGINSENDCAPTURE(api, cCapturePointers, cCaptureBytes, fInput); \
00131
00132 #define BEGINSENDCAPTUREDC(api, cCapturePointers, cCaptureBytes, fInput) \
00133
hdcUse = CreateCompatiblePublicDC(hdc,&hbmDCGray); \
00134
if (hdcUse == (HDC)NULL) { \
00135
return FALSE; \
00136
} \
00137
BEGINSENDCAPTURE(api, cCapturePointers, cCaptureBytes, fInput); \
00138
00139 #define LOCKPWND() \
00140
ThreadLock(pwnd, &tlpwnd); \
00141
cbwin = pci->CallbackWnd; \
00142
pci->CallbackWnd.pwnd = pwndClient; \
00143
pci->CallbackWnd.hwnd = HW(pwnd);
00144
00145 #define UNLOCKPWND() \
00146
pci->CallbackWnd = cbwin; \
00147
ThreadUnlock(&tlpwnd);
00148
00149 #define MAKECALL(api) \
00150
UserAssert(!(PtiCurrent()->TIF_flags & TIF_INCLEANUP)); \
00151
LeaveCrit(); \
00152
Status = KeUserModeCallback( \
00153
FI_ ## api, \
00154
mp, \
00155
sizeof(*mp), \
00156
&pcbs, \
00157
&cbCBStatus); \
00158
EnterCrit();
00159
00160 #define MAKECALLCAPTURE(api) \
00161
UserAssert(!(PtiCurrent()->TIF_flags & TIF_INCLEANUP)); \
00162
LeaveCrit(); \
00163
Status = (DWORD)KeUserModeCallback( \
00164
FI_ ## api, \
00165
mp, \
00166
mp->CaptureBuf.cbCallback, \
00167
&pcbs, \
00168
&cbCBStatus); \
00169
EnterCrit();
00170
00171 #define MAKECALLCAPTUREDC(api) \
00172
iDC = GreSaveDC(hdc); \
00173
MAKECALLCAPTURE(api) \
00174
GreRestoreDC(hdc, iDC); \
00175
iDC = 0; \
00176
if ((hdcUse != hdc) && NT_SUCCESS(Status)) { \
00177
GreBitBlt(hdc, \
00178
0, \
00179
0, \
00180
gpDispInfo->cxGray, \
00181
gpDispInfo->cyGray, \
00182
hdcUse, \
00183
0, \
00184
0, \
00185
SRCCOPY, \
00186
0); \
00187
}
00188
00189 #define CHECKRETURN() \
00190
if (!NT_SUCCESS(Status) || \
00191
cbCBStatus != sizeof(*pcbs)) { \
00192
goto errorexit; \
00193
} \
00194
try { \
00195
retval = ProbeAndReadStructure(&pcbs->retval, ULONG_PTR); \
00196
} except (W32ExceptionHandler(FALSE, RIP_ERROR)) { \
00197
MSGERROR(); \
00198
}
00199
00200 #define ENDSEND(type, error) \
00201
return (type)retval; \
00202
goto errorexit; \
00203
} \
00204
errorexit: \
00205
return (type)error
00206
00207 #define CLEANUPSENDCAPTURECOMMONDC() \
00208
if(iDC) { \
00209
GreRestoreDC(hdc, iDC); \
00210
} \
00211
if (hdcUse != hdc) { \
00212
GreDeleteDC(hdcUse); \
00213
GreDeleteObject(hbmDCGray); \
00214
} \
00215
00216 #define BEGIN_ENDSENDCAPTURE(type, error) \
00217
exit:
00218 #define _ENDSENDCAPTURE(type, error) \
00219
if (mp != &m && (PVOID)mp != (PVOID)Buffer) { \
00220
if (mp->CaptureBuf.pvVirtualAddress) { \
00221
NTSTATUS Status; \
00222
SIZE_T ulRegionSize = 0; \
00223
\
00224
Status = ZwFreeVirtualMemory(NtCurrentProcess(),\
00225
&mp->CaptureBuf.pvVirtualAddress, \
00226
&ulRegionSize, \
00227
MEM_RELEASE); \
00228
UserAssert(NT_SUCCESS(Status)); \
00229
} \
00230
ThreadUnlockAndFreePool(ptiCurrent, &tlPool); \
00231
} \
00232
return (type)retval; \
00233
goto errorexit; \
00234
} \
00235
errorexit: \
00236
retval = error; \
00237
goto exit; \
00238
errorexitnofreemp:
00239 #define END_ENDSENDCAPTURE(type, error) \
00240
return (type)error
00241
00242
00243 #define ENDSENDCAPTUREDC(type, error) \
00244
BEGIN_ENDSENDCAPTURE(type, error); \
00245
CLEANUPSENDCAPTURECOMMONDC(); \
00246
_ENDSENDCAPTURE(type, error); \
00247
CLEANUPSENDCAPTURECOMMONDC(); \
00248
END_ENDSENDCAPTURE(type, error)
00249
00250 #define ENDSENDCAPTURE(type, error) \
00251
BEGIN_ENDSENDCAPTURE(type, error); \
00252
_ENDSENDCAPTURE(type, error); \
00253
END_ENDSENDCAPTURE(type, error)
00254
00255
00256
#ifdef FE_SB // ENDSENDCAPTUREOUTSTRING()
00257
#define ENDSENDCAPTUREOUTSTRING(type, error) \
00258
exit: \
00259
if (mp != &m && (PVOID)mp != (PVOID)Buffer) { \
00260
if (mp->CaptureBuf.pvVirtualAddress) { \
00261
NTSTATUS Status; \
00262
SIZE_T ulRegionSize = 0; \
00263
\
00264
Status = ZwFreeVirtualMemory(NtCurrentProcess(),\
00265
&mp->CaptureBuf.pvVirtualAddress, \
00266
&ulRegionSize, \
00267
MEM_RELEASE); \
00268
UserAssert(NT_SUCCESS(Status)); \
00269
} \
00270
ThreadUnlockAndFreePool(ptiCurrent, &tlPool); \
00271
} \
00272
if (bInflateWParam) \
00273
PtiCurrent()->TIF_flags &= ~TIF_ANSILENGTH; \
00274
return (type)retval; \
00275
goto errorexit; \
00276
} \
00277
errorexit: \
00278
retval = error; \
00279
goto exit; \
00280
errorexitnofreemp: \
00281
if (bInflateWParam) \
00282
PtiCurrent()->TIF_flags &= ~TIF_ANSILENGTH; \
00283
return (type)error
00284
#endif // FE_SB
00285
00286 #define BEGIN_ENDSENDCAPTUREVOID() \
00287
errorexit:
00288 #define _ENDSENDCAPTUREVOID() \
00289
if (mp != &m && (PVOID)mp != (PVOID)Buffer) { \
00290
if (mp->CaptureBuf.pvVirtualAddress) { \
00291
NTSTATUS Status; \
00292
SIZE_T ulRegionSize = 0; \
00293
\
00294
Status = ZwFreeVirtualMemory(NtCurrentProcess(),\
00295
&mp->CaptureBuf.pvVirtualAddress, \
00296
&ulRegionSize, \
00297
MEM_RELEASE); \
00298
UserAssert(NT_SUCCESS(Status)); \
00299
} \
00300
ThreadUnlockAndFreePool(ptiCurrent, &tlPool); \
00301
} \
00302
return; \
00303
} \
00304
errorexitnofreemp:
00305 #define END_ENDSENDCAPTUREVOID() \
00306
return
00307
00308 #define ENDSENDCAPTUREVOIDDC() \
00309
BEGIN_ENDSENDCAPTUREVOID(); \
00310
CLEANUPSENDCAPTURECOMMONDC(); \
00311
_ENDSENDCAPTUREVOID(); \
00312
CLEANUPSENDCAPTURECOMMONDC(); \
00313
END_ENDSENDCAPTUREVOID()
00314
00315 #define ENDSENDCAPTUREVOID() \
00316
BEGIN_ENDSENDCAPTUREVOID(); \
00317
CLEANUPSENDCAPTURECOMMON(); \
00318
_ENDSENDCAPTUREVOID(); \
00319
CLEANUPSENDCAPTURECOMMON(); \
00320
END_ENDSENDCAPTUREVOID()
00321
00322
00323 #define ENDSENDVOID() \
00324
} \
00325
return
00326
00327 #define MSGERROR() goto errorexit
00328
00329
#ifdef FE_SB // CHECKRETURN1() & ENDSEND1()
00330
#define CHECKRETURN1() \
00331
if (!NT_SUCCESS(Status) || \
00332
cbCBStatus != sizeof(*pcbs)) { \
00333
goto errorexit1; \
00334
} \
00335
try { \
00336
retval = ProbeAndReadStructure(&pcbs->retval, ULONG_PTR); \
00337
} except (W32ExceptionHandler(FALSE, RIP_ERROR)) { \
00338
MSGERROR(); \
00339
}
00340
00341
#define ENDSEND1(type, error) \
00342
return (type)retval; \
00343
goto errorexit1; \
00344
} \
00345
errorexit1: \
00346
return (type)error
00347
00348
#define MSGERROR1() goto errorexit1
00349
#endif // FE_SB
00350
00351
00352
00353
00354 #define MSGDATA() (mp)
00355
00356 #define COPYSTRUCTOPT(x) \
00357
MSGDATA()->p ## x = (p ## x); \
00358
if (p ## x) MSGDATA()->x = *(p ## x);
00359
00360 #define COPYCONSTRECTSTRUCTOPT(x) \
00361
MSGDATA()->p ## x = (LPRECT)(p ## x); \
00362
if (p ## x) MSGDATA()->x = *(p ## x);
00363
00364 #define COPYBYTES(p, cb) \
00365
if (!NT_SUCCESS(CaptureCallbackData(&mp->CaptureBuf, p, cb, &mp->p))) \
00366
goto errorexit;
00367
00368 #define COPYBYTESOPT(p, cb) \
00369
if (p) { \
00370
if (!NT_SUCCESS(CaptureCallbackData(&mp->CaptureBuf, p, cb, &mp->p))) \
00371
goto errorexit; \
00372
} else { \
00373
mp->p = NULL; \
00374
}
00375
00376 #define LARGECOPYBYTES(p, cb) \
00377
if (!NT_SUCCESS(CaptureCallbackData(&mp->CaptureBuf, p, cb, &mp->p))) \
00378
goto errorexit;
00379
00380 #define LARGECOPYBYTES2(src, cb, dest) \
00381
if (!NT_SUCCESS(CaptureCallbackData(&mp->CaptureBuf, src, cb, &mp->dest))) \
00382
goto errorexit;
00383
00384 #define COPYSTRING(s) \
00385
mp->s.Length = (p ## s)->Length; \
00386
mp->s.MaximumLength = (p ## s)->MaximumLength; \
00387
if (!NT_SUCCESS(CaptureCallbackData(&mp->CaptureBuf, \
00388
(p ## s)->Buffer, \
00389
(p ## s)->Length + sizeof(WCHAR), \
00390
&mp->s.Buffer))) \
00391
goto errorexit;
00392
00393 #define COPYSTRINGOPT(s) \
00394
if (p ## s) { \
00395
mp->s.Length = (p ## s)->Length; \
00396
mp->s.MaximumLength = (p ## s)->MaximumLength; \
00397
if (!NT_SUCCESS(CaptureCallbackData(&mp->CaptureBuf, \
00398
(p ## s)->Buffer, \
00399
(p ## s)->Length + sizeof(WCHAR), \
00400
&mp->s.Buffer))) \
00401
goto errorexit; \
00402
} else { \
00403
mp->s.Length = 0; \
00404
mp->s.Buffer = NULL; \
00405
}
00406
00407 #define COPYSTRINGID(s) \
00408
mp->s.Length = (p ## s)->Length; \
00409
mp->s.MaximumLength = (p ## s)->MaximumLength; \
00410
if (mp->s.MaximumLength) { \
00411
if (!NT_SUCCESS(CaptureCallbackData(&mp->CaptureBuf, \
00412
(p ## s)->Buffer, \
00413
(p ## s)->Length + sizeof(WCHAR), \
00414
&mp->s.Buffer))) \
00415
goto errorexit; \
00416
} else { \
00417
mp->s.Buffer = (p ## s)->Buffer; \
00418
}
00419
00420 #define LARGECOPYSTRINGLPWSTR(ps, psz) \
00421
if (!NT_SUCCESS(CaptureCallbackData(&mp->CaptureBuf, \
00422
(ps)->Buffer, \
00423
(ps)->Length + sizeof(WCHAR), \
00424
(PVOID *)&mp->psz))) \
00425
goto errorexit;
00426
00427 #define LARGECOPYSTRINGLPSTR(ps, psz) \
00428
if (!NT_SUCCESS(CaptureCallbackData(&mp->CaptureBuf, \
00429
(ps)->Buffer, \
00430
(ps)->Length + 1, \
00431
(PVOID *)&mp->psz))) \
00432
goto errorexit;
00433
00434 #define LARGECOPYSTRINGLPWSTRA(ps, psz) \
00435
if (!NT_SUCCESS(CaptureAnsiCallbackData(&mp->CaptureBuf, \
00436
(ps)->Buffer, \
00437
((ps)->Length / sizeof(WCHAR)) + 1, \
00438
(PVOID *)&mp->psz))) \
00439
goto errorexit;
00440
00441 #define LARGECOPYSTRINGLPSTRW(ps, psz) \
00442
if (!NT_SUCCESS(CaptureUnicodeCallbackData(&mp->CaptureBuf, \
00443
(ps)->Buffer, \
00444
((ps)->Length + 1) * sizeof(WCHAR), \
00445
(PVOID *)&mp->psz))) \
00446
goto errorexit; \
00447
00448 #define LARGECOPYSTRINGLPWSTROPT(ps, psz) \
00449
if (ps) { \
00450
if (!NT_SUCCESS(CaptureCallbackData(&mp->CaptureBuf, \
00451
(ps)->Buffer, \
00452
(ps)->Length + sizeof(WCHAR), \
00453
(PVOID *)&mp->psz))) \
00454
goto errorexit; \
00455
} else { \
00456
mp->psz = NULL; \
00457
}
00458
00459 #define LARGECOPYSTRINGLPSTROPT(ps, psz) \
00460
if (ps) { \
00461
if (!NT_SUCCESS(CaptureCallbackData(&mp->CaptureBuf, \
00462
(ps)->Buffer, \
00463
(ps)->Length + sizeof(UCHAR), \
00464
(PVOID *)&mp->psz))) \
00465
goto errorexit; \
00466
} else { \
00467
mp->psz = NULL; \
00468
}
00469
00470 #define LARGECOPYSTRINGLPWSTROPTA(ps, psz) \
00471
if (ps) { \
00472
if (!NT_SUCCESS(CaptureAnsiCallbackData(&mp->CaptureBuf, \
00473
(ps)->Buffer, \
00474
((ps)->Length / sizeof(WCHAR)) + 1, \
00475
(PVOID *)&mp->psz))) \
00476
goto errorexit; \
00477
} else { \
00478
mp->psz = NULL; \
00479
}
00480
00481
00482
00483
00484 #define BEGINCOPYOUT() \
00485
if ((psms == NULL || ((psms->flags & (SMF_SENDERDIED | SMF_REPLY)) == 0)) \
00486
&& !(dwSCMSFlags & SCMS_FLAGS_INONLY)) {
00487
00488 #define ENDCOPYOUT() \
00489
}
00490
00491
00492
00493
00494 #define OUTSTRUCT(pstruct, type) \
00495
try { \
00496
*(pstruct) = ProbeAndReadStructure(((type *)pcbs->pOutput), type); \
00497
} except (W32ExceptionHandler(FALSE, RIP_ERROR)) { \
00498
MSGERROR(); \
00499
}
00500
00501
00502
00503
00504 #define OUTBITMASK(pstruct, type, mask) \
00505
try { \
00506
type flags = ProbeAndReadStructure(((type *)pcbs->pOutput), type); \
00507
COPY_FLAG(*(pstruct), flags, mask); \
00508
} except (W32ExceptionHandler(FALSE, RIP_ERROR)) { \
00509
MSGERROR(); \
00510
}
00511
00512
#ifdef FE_SB // COPYOUTLPWSTRLIMIT()
00513
00514
#define COPYOUTLPWSTRLIMIT(pstr, cch) \
00515
try { \
00516
retval = CalcOutputStringSize(pcbs,(DWORD)retval,pstr->bAnsi,fAnsiReceiver); \
00517
CopyOutputString(pcbs, pstr, cch, fAnsiReceiver); \
00518
} except (W32ExceptionHandler(FALSE, RIP_ERROR)) { \
00519
MSGERROR(); \
00520
}
00521
#else
00522 #define COPYOUTLPWSTRLIMIT(pstr, cch) \
00523
try { \
00524
CopyOutputString(pcbs, pstr, cch, fAnsiReceiver); \
00525
} except (W32ExceptionHandler(FALSE, RIP_ERROR)) { \
00526
MSGERROR(); \
00527
}
00528
#endif // FE_SB
00529
00530 #define RESERVEBYTES(cb, dest, cbdest) \
00531
if (!NT_SUCCESS(AllocateCallbackData(&mp->CaptureBuf, \
00532
cb, (PVOID *)&mp->dest))) \
00533
goto errorexit; \
00534
mp->cbdest = cb;
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545 PVOID
AllocCallbackMessage(
00546 DWORD cbBaseMsg,
00547 DWORD cPointers,
00548 SIZE_T cbCapture,
00549 PBYTE pStackBuffer,
00550 BOOL fInput)
00551 {
00552
PCAPTUREBUF pcb;
00553
00554
if (cPointers == 0)
00555
return NULL;
00556
00557
00558
00559
00560 cbBaseMsg = (cbBaseMsg +
PADSIZE) & ~
PADSIZE;
00561 cbBaseMsg += (cPointers *
sizeof(PVOID));
00562 cbCapture = (cbCapture + (
PADSIZE * cPointers)) & ~
PADSIZE;
00563
00564
00565
00566
00567
00568
00569
if (cbCapture >
CALLBACKSTACKLIMIT) {
00570
NTSTATUS Status;
00571
00572
00573
00574
00575 pcb = UserAllocPoolWithQuota(cbBaseMsg, TAG_CALLBACK);
00576
if (pcb ==
NULL)
00577
return NULL;
00578
00579
00580
00581
00582 pcb->
pvVirtualAddress =
NULL;
00583
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
00584 &pcb->
pvVirtualAddress, 0, &cbCapture,
00585 MEM_COMMIT, PAGE_READWRITE);
00586
if (!
NT_SUCCESS(
Status)) {
00587 RIPMSG2(RIP_WARNING,
"AllocCallbackMessage: ZwAllocateVirtualMemory failed. Status:%#lx. Size:%#lx",
00588
Status, cbCapture);
00589 UserFreePool(pcb);
00590
return NULL;
00591 }
00592 pcb->
pbFree = pcb->
pvVirtualAddress;
00593 pcb->
cbCallback = cbBaseMsg;
00594 }
else {
00595
00596
00597
00598
00599
00600
if (cbBaseMsg + cbCapture >
CBBUFSIZE) {
00601 pcb = UserAllocPoolWithQuota((ULONG)(cbBaseMsg + cbCapture), TAG_CALLBACK);
00602
if (pcb ==
NULL)
00603
return NULL;
00604 }
else {
00605 pcb = (
PCAPTUREBUF)pStackBuffer;
00606 }
00607 pcb->
pbFree = (
PBYTE)pcb + cbBaseMsg;
00608 pcb->
pvVirtualAddress =
NULL;
00609
00610
00611
00612
00613
00614
if (fInput)
00615 pcb->
cbCallback = cbBaseMsg + (ULONG)cbCapture;
00616
else
00617 pcb->
cbCallback = cbBaseMsg;
00618 }
00619
00620
00621
00622
00623 pcb->
cbCapture = (ULONG)cbCapture;
00624 pcb->
cCapturedPointers = 0;
00625 pcb->
offPointers = cbBaseMsg - (cPointers *
sizeof(PVOID));
00626
00627
return (PVOID)pcb;
00628 }
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 NTSTATUS CaptureCallbackData(
00640
PCAPTUREBUF pcb,
00641 PVOID pData,
00642 DWORD cbData,
00643 PVOID *ppDest)
00644 {
00645
PBYTE pbBuffer;
00646
00647
00648
00649
00650
00651
if (pData ==
NULL) {
00652 *ppDest =
NULL;
00653
return STATUS_SUCCESS;
00654 }
00655
00656
00657
00658
00659
if (cbData > pcb->
cbCapture) {
00660
return STATUS_BUFFER_OVERFLOW;
00661 }
00662
00663 pbBuffer = pcb->
pbFree;
00664 pcb->
pbFree = pbBuffer + ((cbData +
PADSIZE) & ~
PADSIZE);
00665
00666
try {
00667 RtlCopyMemory(pbBuffer, pData, cbData);
00668 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
00669
return STATUS_ACCESS_VIOLATION;
00670 }
00671
00672
00673
00674
00675
00676
if (pcb->
pvVirtualAddress)
00677 *ppDest = pbBuffer;
00678
else {
00679 *ppDest = (
PBYTE)(pbBuffer - (
PBYTE)pcb);
00680 ((LPDWORD)((
PBYTE)pcb + pcb->
offPointers))[pcb->
cCapturedPointers++] =
00681 (
DWORD)((
PBYTE)ppDest - (
PBYTE)pcb);
00682 }
00683
00684
return STATUS_SUCCESS;
00685 }
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695 NTSTATUS AllocateCallbackData(
00696
PCAPTUREBUF pcb,
00697 DWORD cbData,
00698 PVOID *ppDest)
00699 {
00700
PBYTE pbBuffer;
00701
00702
00703
00704
00705
if (cbData > pcb->
cbCapture) {
00706
return STATUS_BUFFER_OVERFLOW;
00707 }
00708
00709 pbBuffer = pcb->
pbFree;
00710 pcb->
pbFree = pbBuffer + ((cbData +
PADSIZE) & ~
PADSIZE);
00711
00712
00713
00714
00715
00716
if (pcb->
pvVirtualAddress)
00717 *ppDest = pbBuffer;
00718
else {
00719 *ppDest = (
PBYTE)(pbBuffer - (
PBYTE)pcb);
00720 ((LPDWORD)((
PBYTE)pcb + pcb->
offPointers))[pcb->
cCapturedPointers++] =
00721 (
DWORD)((
PBYTE)ppDest - (
PBYTE)pcb);
00722 }
00723
00724
return STATUS_SUCCESS;
00725 }
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736 NTSTATUS CaptureAnsiCallbackData(
00737
PCAPTUREBUF pcb,
00738 PVOID pData,
00739 DWORD cbData,
00740 PVOID *ppDest)
00741 {
00742
PBYTE pbBuffer;
00743 ULONG nCharsInAnsiString;
00744
00745
00746
00747
00748
00749
if (pData ==
NULL) {
00750 *ppDest =
NULL;
00751
return STATUS_SUCCESS;
00752 }
00753
00754
00755
00756
00757
#ifdef FE_SB // CaptureAnsiCallbackData()
00758
00759
00760
00761
if ((cbData *
sizeof(WORD)) > pcb->
cbCapture) {
00762
#else
00763
if (cbData > pcb->
cbCapture) {
00764
#endif // FE_SB
00765
return STATUS_BUFFER_OVERFLOW;
00766 }
00767
00768 pbBuffer = pcb->
pbFree;
00769
00770
00771
00772
00773
try {
00774
#ifdef FE_SB // CaptureAnsiCallbackData()
00775
00776
00777
00778
if (!
NT_SUCCESS(
RtlUnicodeToMultiByteN(
00779 (PCH)pbBuffer,
00780
IS_DBCS_ENABLED() ? cbData *
DBCS_CHARSIZE : cbData,
00781 &nCharsInAnsiString,
00782 (PWCH)pData,
00783 cbData *
sizeof(WCHAR)
00784 ))) {
00785
#else
00786
if (!
NT_SUCCESS(
RtlUnicodeToMultiByteN(
00787 (PCH)pbBuffer,
00788 cbData,
00789 &nCharsInAnsiString,
00790 (PWCH)pData,
00791 cbData *
sizeof(WCHAR)
00792 ))) {
00793
#endif // FE_SB
00794
return STATUS_UNSUCCESSFUL;
00795 }
00796 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
00797
return STATUS_ACCESS_VIOLATION;
00798 }
00799
00800
00801
00802
00803
#ifdef FE_SB // CaptureAnsiCallbackData()
00804
00805
00806
00807 pcb->
pbFree = pbBuffer + ((nCharsInAnsiString +
PADSIZE) & ~
PADSIZE);
00808 pcb->
cbCapture -= nCharsInAnsiString;
00809
#else
00810
pcb->
pbFree = pbBuffer + ((cbData +
PADSIZE) & ~
PADSIZE);
00811 pcb->
cbCapture -= cbData;
00812
#endif // FE_SB
00813
00814
00815
00816
00817
00818
if (pcb->
pvVirtualAddress)
00819 *ppDest = pbBuffer;
00820
else {
00821 *ppDest = (
PBYTE)(pbBuffer - (
PBYTE)pcb);
00822 ((LPDWORD)((
PBYTE)pcb + pcb->
offPointers))[pcb->
cCapturedPointers++] =
00823 (
DWORD)((
PBYTE)ppDest - (
PBYTE)pcb);
00824 }
00825
00826
return STATUS_SUCCESS;
00827 }
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839 NTSTATUS CaptureUnicodeCallbackData(
00840
PCAPTUREBUF pcb,
00841 PVOID pData,
00842 DWORD cbData,
00843 PVOID *ppDest)
00844 {
00845
PBYTE pbBuffer;
00846 ULONG nCharsInUnicodeString;
00847
00848
00849
00850
00851
00852
if (pData ==
NULL) {
00853 *ppDest =
NULL;
00854
return STATUS_SUCCESS;
00855 }
00856
00857
00858
00859
00860
if (cbData > pcb->
cbCapture) {
00861
return STATUS_BUFFER_OVERFLOW;
00862 }
00863
00864 pbBuffer = pcb->
pbFree;
00865
00866
00867
00868
00869
try {
00870
if (!
NT_SUCCESS(
RtlMultiByteToUnicodeN(
00871 (PWCH)pbBuffer,
00872 cbData,
00873 &nCharsInUnicodeString,
00874 (PCH)pData,
00875 cbData /
sizeof(WCHAR)
00876 ))) {
00877
return STATUS_UNSUCCESSFUL;
00878 }
00879 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
00880
return STATUS_ACCESS_VIOLATION;
00881 }
00882
00883
00884
00885
00886 pcb->
pbFree = pbBuffer + ((cbData +
PADSIZE) & ~
PADSIZE);
00887 pcb->
cbCapture -= cbData;
00888
00889
00890
00891
00892
00893
if (pcb->
pvVirtualAddress)
00894 *ppDest = pbBuffer;
00895
else {
00896 *ppDest = (
PBYTE)(pbBuffer - (
PBYTE)pcb);
00897 ((LPDWORD)((
PBYTE)pcb + pcb->
offPointers))[pcb->
cCapturedPointers++] =
00898 (
DWORD)((
PBYTE)ppDest - (
PBYTE)pcb);
00899 }
00900
00901
return STATUS_SUCCESS;
00902 }
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922 VOID CopyOutputString(
00923
PCALLBACKSTATUS pcbs,
00924
PLARGE_STRING pstr,
00925 UINT cchLimit,
00926 BOOL fAnsi)
00927 {
00928
UINT cch;
00929
00930
ProbeForRead(
pcbs->pOutput,
pcbs->cbOutput,
00931 fAnsi ?
sizeof(
BYTE) :
sizeof(WORD));
00932
if (!pstr->
bAnsi) {
00933
if (fAnsi) {
00934 cch = MBToWCS((LPSTR)
pcbs->pOutput, (
UINT)
pcbs->retval,
00935 (LPWSTR *)&pstr->
Buffer, cchLimit,
FALSE);
00936
if (cch < cchLimit) {
00937
00938
00939
00940 ((LPWSTR)pstr->
Buffer)[cch] = 0;
00941 cchLimit = cch;
00942 }
00943 }
else {
00944 cchLimit =
wcsncpycch(pstr->
Buffer, (LPWSTR)
pcbs->pOutput, cchLimit);
00945
00946 }
00947 pstr->
Length = cchLimit *
sizeof(WCHAR);
00948 }
else {
00949
if (fAnsi) {
00950 cchLimit =
strncpycch((LPSTR)pstr->
Buffer,
00951
00952 (LPSTR)
pcbs->pOutput, cchLimit);
00953 }
else {
00954 cch = WCSToMB((LPWSTR)
pcbs->pOutput, (
UINT)
pcbs->retval,
00955 (LPSTR *)&pstr->
Buffer, cchLimit,
FALSE);
00956
if (cch < cchLimit) {
00957
00958
00959
00960 ((LPSTR)pstr->
Buffer)[cch] = 0;
00961 cchLimit = cch;
00962 }
00963 }
00964 pstr->
Length = cchLimit;
00965 }
00966 }
00967
00968
#ifdef FE_SB // CalcOutputStringSize()
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
DWORD CalcOutputStringSize(
00979
PCALLBACKSTATUS pcbs,
00980 DWORD cchText,
00981 BOOL fAnsiSender,
00982 BOOL fAnsiReceiver)
00983 {
00984 ULONG cch;
00985
00986
ProbeForRead(
pcbs->pOutput,
pcbs->cbOutput,
00987 fAnsiReceiver ?
sizeof(BYTE) :
sizeof(WORD));
00988
if (!fAnsiSender) {
00989
if (fAnsiReceiver) {
00990
RtlMultiByteToUnicodeSize(&cch,(LPSTR)
pcbs->pOutput,cchText);
00991 cch /=
sizeof(WCHAR);
00992 }
else {
00993 cch = cchText;
00994 }
00995 }
else {
00996
if (fAnsiReceiver) {
00997 cch = cchText;
00998 }
else {
00999
RtlUnicodeToMultiByteSize(&cch,(LPWSTR)
pcbs->pOutput,cchText *
sizeof(WCHAR));
01000 }
01001 }
01002
01003
return ((
DWORD)cch);
01004 }
01005
#endif // FE_SB
01006
01007
01008
01009
01010
01011
01012
01013
#include "ntcb.h"