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

ssend.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: ssend.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * Server side sending stubs 00007 * 00008 * 07-06-91 ScottLu Created. 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 * Callback setup and control macros 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 * Callback IN parameter macros 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 * Wrappers to determine whether copy out should be done. 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 * Callback OUT paramter macros 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 * flags field with mask (propagate back bits in mask only) 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 // should we insert IS_DBCS_ENABLED() in COPYOUTLPWSTRLIMIT ? 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 * AllocCallbackMessage 00538 * 00539 * Allocates a callback message from pool memory and reserves space 00540 * for arguments to captured later. 00541 * 00542 * 03-13-95 JimA Created. 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 * Compute allocation sizes 00559 */ 00560 cbBaseMsg = (cbBaseMsg + PADSIZE) & ~PADSIZE; 00561 cbBaseMsg += (cPointers * sizeof(PVOID)); 00562 cbCapture = (cbCapture + (PADSIZE * cPointers)) & ~PADSIZE; 00563 00564 /* 00565 * If the captured data is greater than a page, place it 00566 * in a section. Otherwise, put the message and the 00567 * data in a single block of pool 00568 */ 00569 if (cbCapture > CALLBACKSTACKLIMIT) { 00570 NTSTATUS Status; 00571 00572 /* 00573 * Allocate the message buffer 00574 */ 00575 pcb = UserAllocPoolWithQuota(cbBaseMsg, TAG_CALLBACK); 00576 if (pcb == NULL) 00577 return NULL; 00578 00579 /* 00580 * Allocate the virtual memory 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 * If the message is too big to save on the stack, allocate 00598 * the buffer from pool. 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 * If this callback is passing data to the client, include the 00612 * captured data in the message. Otherwise, only pass the message. 00613 */ 00614 if (fInput) 00615 pcb->cbCallback = cbBaseMsg + (ULONG)cbCapture; 00616 else 00617 pcb->cbCallback = cbBaseMsg; 00618 } 00619 00620 /* 00621 * Initialize the capture buffer 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 * CaptureCallbackData 00633 * 00634 * Captures data into a callback structure. 00635 * 00636 * 03-13-95 JimA Created. 00637 \***************************************************************************/ 00638 00639 NTSTATUS CaptureCallbackData( 00640 PCAPTUREBUF pcb, 00641 PVOID pData, 00642 DWORD cbData, 00643 PVOID *ppDest) 00644 { 00645 PBYTE pbBuffer; 00646 00647 /* 00648 * If the data pointer is NULL, the out pointer will be 00649 * NULL 00650 */ 00651 if (pData == NULL) { 00652 *ppDest = NULL; 00653 return STATUS_SUCCESS; 00654 } 00655 00656 /* 00657 * Allocate space from the message buffer 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 * Fix up offsets to data. If the data is going into a section 00674 * use the real pointer and don't compute offsets. 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 * AllocateCallbackData 00689 * 00690 * Allocates space from a callback structure. 00691 * 00692 * 05-08-95 JimA Created. 00693 \***************************************************************************/ 00694 00695 NTSTATUS AllocateCallbackData( 00696 PCAPTUREBUF pcb, 00697 DWORD cbData, 00698 PVOID *ppDest) 00699 { 00700 PBYTE pbBuffer; 00701 00702 /* 00703 * Allocate space from the message buffer 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 * Fix up offsets to data. If the data is going into a section 00714 * use the real pointer and don't compute offsets. 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 * CaptureAnsiCallbackData 00729 * 00730 * Converts Unicode to ANSI data and captures the result 00731 * into a callback structure. 00732 * 00733 * 03-13-95 JimA Created. 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 * If the data pointer is NULL, the out pointer will be 00747 * NULL 00748 */ 00749 if (pData == NULL) { 00750 *ppDest = NULL; 00751 return STATUS_SUCCESS; 00752 } 00753 00754 /* 00755 * Allocate space from the message buffer 00756 */ 00757 #ifdef FE_SB // CaptureAnsiCallbackData() 00758 /* 00759 * Reserve enough space for DBCS. 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 * Convert the unicode string to ANSI 00772 */ 00773 try { 00774 #ifdef FE_SB // CaptureAnsiCallbackData() 00775 /* 00776 * Enough space for keep DBCS string. 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 * Translation succeeded. 00802 */ 00803 #ifdef FE_SB // CaptureAnsiCallbackData() 00804 /* 00805 * nCharsInAnsiString is actual bytes wriiten in message area. 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 * Fix up offsets to data. If the data is going into a section 00816 * use the real pointer and don't compute offsets. 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 * CaptureUnicodeCallbackData 00832 * 00833 * Converts ANSI to Unicode data and captures the result 00834 * into a callback structure. 00835 * 00836 * 03-31-95 JimA Created. 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 * If the data pointer is NULL, the out pointer will be 00850 * NULL 00851 */ 00852 if (pData == NULL) { 00853 *ppDest = NULL; 00854 return STATUS_SUCCESS; 00855 } 00856 00857 /* 00858 * Allocate space from the message buffer 00859 */ 00860 if (cbData > pcb->cbCapture) { 00861 return STATUS_BUFFER_OVERFLOW; 00862 } 00863 00864 pbBuffer = pcb->pbFree; 00865 00866 /* 00867 * Convert the ANSI string to unicode 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 * Translation succeeded. 00885 */ 00886 pcb->pbFree = pbBuffer + ((cbData + PADSIZE) & ~PADSIZE); 00887 pcb->cbCapture -= cbData; 00888 00889 /* 00890 * Fix up offsets to data. If the data is going into a section 00891 * use the real pointer and don't compute offsets. 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 * CopyOutputString 00907 * 00908 * Copies a callback output string to the output buffer and performs 00909 * any necessary ANSI/Unicode translation. 00910 * 00911 * Copies up to cchLimit characters, possibly including a null terminator. 00912 * 00913 * A null terminator is placed in pstr->Buffer only if the number of (non-null) 00914 * characters obtained is less than cchLimit. 00915 * pstr->Length may be set larger than necessary: ie: it may sometimes indicate 00916 * a string longer than that which is null terminated. This is a deficiency in 00917 * the current implementation. 00918 * 00919 * 05-08-95 JimA Created. 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 * Add a null terminator and ensure an accurate pstr->Length 00939 */ 00940 ((LPWSTR)pstr->Buffer)[cch] = 0; 00941 cchLimit = cch; 00942 } 00943 } else { 00944 cchLimit = wcsncpycch(pstr->Buffer, (LPWSTR)pcbs->pOutput, cchLimit); 00945 // wcsncpy(pstr->Buffer, (LPWSTR)pcbs->pOutput, cchLimit); 00946 } 00947 pstr->Length = cchLimit * sizeof(WCHAR); 00948 } else { 00949 if (fAnsi) { 00950 cchLimit = strncpycch((LPSTR)pstr->Buffer, 00951 // strncpy((LPSTR)pstr->Buffer, 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 * Add a null terminator and ensure an accurate pstr->Length 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 * CalcOutputStringSize() 00971 * 00972 * Copies a callback output string to the output buffer and performs 00973 * any necessary ANSI/Unicode translation. 00974 * 00975 * 03-14-96 HideyukN Created. 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 * include the stub definition file 01010 * 01011 \**************************************************************************/ 01012 01013 #include "ntcb.h"

Generated on Sat May 15 19:41:51 2004 for test by doxygen 1.3.7