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

ddetrack.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: ddetrack.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * client sied DDE tracking routines 00007 * 00008 * 10-22-91 sanfords created 00009 \***************************************************************************/ 00010 00011 #include "precomp.h" 00012 #pragma hdrstop 00013 00014 00015 DWORD _ClientCopyDDEIn1( 00016 HANDLE hClient, // client handle to dde data or ddepack data 00017 PINTDDEINFO pi) // info for transfer 00018 { 00019 PBYTE pData; 00020 DWORD flags; 00021 00022 // 00023 // zero out everything but the flags 00024 // 00025 flags = pi->flags; 00026 RtlZeroMemory(pi, sizeof(INTDDEINFO)); 00027 pi->flags = flags; 00028 USERGLOBALLOCK(hClient, pData); 00029 00030 if (pData == NULL) { // bad hClient 00031 RIPMSG0(RIP_WARNING, "_ClientCopyDDEIn1:GlobalLock failed."); 00032 return (FAIL_POST); 00033 } 00034 00035 if (flags & XS_PACKED) { 00036 00037 if (UserGlobalSize(hClient) < sizeof(DDEPACK)) { 00038 /* 00039 * must be a low memory condition. fail. 00040 */ 00041 return(FAIL_POST); 00042 } 00043 00044 pi->DdePack = *(PDDEPACK)pData; 00045 USERGLOBALUNLOCK(hClient); 00046 UserGlobalFree(hClient); // packed data handles are not WOW matched. 00047 hClient = NULL; 00048 00049 if (!(flags & (XS_LOHANDLE | XS_HIHANDLE))) { 00050 if (flags & XS_EXECUTE && flags & XS_FREESRC) { 00051 /* 00052 * free execute ACK data 00053 */ 00054 WOWGLOBALFREE((HANDLE)pi->DdePack.uiHi); 00055 } 00056 return (DO_POST); // no direct data 00057 } 00058 00059 if (flags & XS_LOHANDLE) { 00060 pi->hDirect = (HANDLE)pi->DdePack.uiLo; 00061 } else { 00062 pi->hDirect = (HANDLE)pi->DdePack.uiHi; 00063 } 00064 00065 if (pi->hDirect == 0) { 00066 return (DO_POST); // must be warm link 00067 } 00068 00069 USERGLOBALLOCK(pi->hDirect, pi->pDirect); 00070 if (pi->pDirect == NULL) { 00071 RIPMSG1(RIP_ERROR, "_ClientCopyDDEIn1:GlobalLock failed for hDirect %lx.",pi->hDirect); 00072 return FAILNOFREE_POST; 00073 } 00074 pData = pi->pDirect; 00075 pi->cbDirect = (UINT)UserGlobalSize(pi->hDirect); 00076 00077 } else { // not packed - must be execute data or we wouldn't be called 00078 00079 UserAssert(flags & XS_EXECUTE); 00080 00081 pi->cbDirect = (UINT)UserGlobalSize(hClient); 00082 pi->hDirect = hClient; 00083 pi->pDirect = pData; 00084 hClient = NULL; 00085 } 00086 00087 if (flags & XS_DATA) { 00088 PDDE_DATA pDdeData = (PDDE_DATA)pData; 00089 00090 /* 00091 * Assert that the hClient has been freed. If not this code will return 00092 * the wrong thing on failure 00093 */ 00094 UserAssert(flags & XS_PACKED); 00095 00096 // 00097 // check here for indirect data 00098 // 00099 00100 switch (pDdeData->wFmt) { 00101 case CF_BITMAP: 00102 case CF_DSPBITMAP: 00103 // 00104 // Imediately following the dde data header is a bitmap handle. 00105 // 00106 UserAssert(pi->cbDirect >= sizeof(DDE_DATA)); 00107 pi->hIndirect = (HANDLE)pDdeData->Data; 00108 if (pi->hIndirect == 0) { 00109 RIPMSG0(RIP_WARNING, "_ClientCopyDDEIn1:GdiConvertBitmap failed"); 00110 return(FAILNOFREE_POST); 00111 } 00112 // pi->cbIndirect = 0; // zero init. 00113 // pi->pIndirect = NULL; // zero init. 00114 pi->flags |= XS_BITMAP; 00115 break; 00116 00117 case CF_DIB: 00118 // 00119 // Imediately following the dde data header is a global data handle 00120 // to the DIB bits. 00121 // 00122 UserAssert(pi->cbDirect >= sizeof(DDE_DATA)); 00123 pi->flags |= XS_DIB; 00124 pi->hIndirect = (HANDLE)pDdeData->Data; 00125 USERGLOBALLOCK(pi->hIndirect, pi->pIndirect); 00126 if (pi->pIndirect == NULL) { 00127 RIPMSG0(RIP_WARNING, "_ClientCopyDDEIn1:CF_DIB GlobalLock failed."); 00128 return (FAILNOFREE_POST); 00129 } 00130 pi->cbIndirect = (UINT)UserGlobalSize(pi->hIndirect); 00131 break; 00132 00133 case CF_PALETTE: 00134 UserAssert(pi->cbDirect >= sizeof(DDE_DATA)); 00135 pi->hIndirect = (HANDLE) pDdeData->Data; 00136 if (pi->hIndirect == 0) { 00137 RIPMSG0(RIP_WARNING, "_ClientCopyDDEIn1:GdiConvertPalette failed."); 00138 return(FAILNOFREE_POST); 00139 } 00140 // pi->cbIndirect = 0; // zero init. 00141 // pi->pIndirect = NULL; // zero init. 00142 pi->flags |= XS_PALETTE; 00143 break; 00144 00145 case CF_DSPMETAFILEPICT: 00146 case CF_METAFILEPICT: 00147 // 00148 // This format holds a global data handle which contains 00149 // a METAFILEPICT structure that in turn contains 00150 // a GDI metafile. 00151 // 00152 UserAssert(pi->cbDirect >= sizeof(DDE_DATA)); 00153 pi->hIndirect = GdiConvertMetaFilePict((HANDLE)pDdeData->Data); 00154 if (pi->hIndirect == 0) { 00155 RIPMSG0(RIP_WARNING, "_ClientCopyDDEIn1:GdiConvertMetaFilePict failed"); 00156 return(FAILNOFREE_POST); 00157 } 00158 // pi->cbIndirect = 0; // zero init. 00159 // pi->pIndirect = NULL; // zero init. 00160 pi->flags |= XS_METAFILEPICT; 00161 break; 00162 00163 case CF_ENHMETAFILE: 00164 case CF_DSPENHMETAFILE: 00165 UserAssert(pi->cbDirect >= sizeof(DDE_DATA)); 00166 pi->hIndirect = GdiConvertEnhMetaFile((HENHMETAFILE)pDdeData->Data); 00167 if (pi->hIndirect == 0) { 00168 RIPMSG0(RIP_WARNING, "_ClientCopyDDEIn1:GdiConvertEnhMetaFile failed"); 00169 return(FAILNOFREE_POST); 00170 } 00171 // pi->cbIndirect = 0; // zero init. 00172 // pi->pIndirect = NULL; // zero init. 00173 pi->flags |= XS_ENHMETAFILE; 00174 break; 00175 } 00176 } 00177 00178 return (DO_POST); 00179 } 00180 00181 00182 /* 00183 * unlocks and frees DDE data pointers as appropriate 00184 */ 00185 VOID _ClientCopyDDEIn2( 00186 PINTDDEINFO pi) 00187 { 00188 if (pi->cbDirect) { 00189 USERGLOBALUNLOCK(pi->hDirect); 00190 if (pi->flags & XS_FREESRC) { 00191 WOWGLOBALFREE(pi->hDirect); 00192 } 00193 } 00194 00195 if (pi->cbIndirect) { 00196 USERGLOBALUNLOCK(pi->hIndirect); 00197 if (pi->flags & XS_FREESRC) { 00198 WOWGLOBALFREE(pi->hIndirect); 00199 } 00200 } 00201 } 00202 00203 00204 00205 /* 00206 * returns fHandleValueChanged. 00207 */ 00208 BOOL FixupDdeExecuteIfNecessary( 00209 HGLOBAL *phCommands, 00210 BOOL fNeedUnicode) 00211 { 00212 UINT cbLen; 00213 UINT cbSrc = (UINT)GlobalSize(*phCommands); 00214 LPVOID pstr; 00215 HGLOBAL hTemp; 00216 BOOL fHandleValueChanged = FALSE; 00217 00218 USERGLOBALLOCK(*phCommands, pstr); 00219 00220 if (cbSrc && pstr != NULL) { 00221 BOOL fIsUnicodeText; 00222 #ifdef ISTEXTUNICODE_WORKS 00223 int flags; 00224 00225 flags = (IS_TEXT_UNICODE_UNICODE_MASK | 00226 IS_TEXT_UNICODE_REVERSE_MASK | 00227 (IS_TEXT_UNICODE_NOT_UNICODE_MASK & 00228 (~IS_TEXT_UNICODE_ILLEGAL_CHARS)) | 00229 IS_TEXT_UNICODE_NOT_ASCII_MASK); 00230 fIsUnicodeText = RtlIsTextUnicode(pstr, cbSrc - 2, &flags); 00231 #else 00232 fIsUnicodeText = ((cbSrc >= sizeof(WCHAR)) && (((LPSTR)pstr)[1] == '\0')); 00233 #endif 00234 if (!fIsUnicodeText && fNeedUnicode) { 00235 LPWSTR pwsz; 00236 /* 00237 * Contents needs to be UNICODE. 00238 */ 00239 cbLen = strlen(pstr) + 1; 00240 cbSrc = min(cbSrc, cbLen); 00241 pwsz = UserLocalAlloc(HEAP_ZERO_MEMORY, cbSrc * sizeof(WCHAR)); 00242 if (pwsz != NULL) { 00243 if (NT_SUCCESS(RtlMultiByteToUnicodeN( 00244 pwsz, 00245 cbSrc * sizeof(WCHAR), 00246 NULL, 00247 (PCHAR)pstr, 00248 cbSrc))) { 00249 USERGLOBALUNLOCK(*phCommands); 00250 if ((hTemp = GlobalReAlloc( 00251 *phCommands, 00252 cbSrc * sizeof(WCHAR), 00253 GMEM_MOVEABLE)) != NULL) { 00254 fHandleValueChanged = (hTemp != *phCommands); 00255 *phCommands = hTemp; 00256 USERGLOBALLOCK(*phCommands, pstr); 00257 pwsz[cbSrc - 1] = L'\0'; 00258 wcscpy(pstr, pwsz); 00259 } 00260 } 00261 UserLocalFree(pwsz); 00262 } 00263 } else if (fIsUnicodeText && !fNeedUnicode) { 00264 LPSTR psz; 00265 /* 00266 * Contents needs to be ANSI. 00267 */ 00268 cbLen = (wcslen(pstr) + 1) * sizeof(WCHAR); 00269 cbSrc = min(cbSrc, cbLen); 00270 psz = UserLocalAlloc(HEAP_ZERO_MEMORY, cbSrc); 00271 if (psz != NULL) { 00272 if (NT_SUCCESS(RtlUnicodeToMultiByteN( 00273 psz, 00274 cbSrc, 00275 NULL, 00276 (PWSTR)pstr, 00277 cbSrc))) { 00278 USERGLOBALUNLOCK(*phCommands); 00279 if ((hTemp = GlobalReAlloc( 00280 *phCommands, 00281 cbSrc / sizeof(WCHAR), 00282 GMEM_MOVEABLE)) != NULL) { 00283 fHandleValueChanged = (hTemp != *phCommands); 00284 *phCommands = hTemp; 00285 USERGLOBALLOCK(*phCommands, pstr); 00286 UserAssert(pstr); 00287 psz[cbSrc - 1] = '\0'; 00288 strcpy(pstr, psz); 00289 } 00290 } 00291 UserLocalFree(psz); 00292 } 00293 } 00294 USERGLOBALUNLOCK(*phCommands); 00295 } 00296 return(fHandleValueChanged); 00297 } 00298 00299 00300 00301 /* 00302 * Allocates and locks global handles as appropriate in preperation 00303 * for thunk copying. 00304 */ 00305 HANDLE _ClientCopyDDEOut1( 00306 PINTDDEINFO pi) 00307 { 00308 HANDLE hDdePack = NULL; 00309 PDDEPACK pDdePack = NULL; 00310 00311 if (pi->flags & XS_PACKED) { 00312 /* 00313 * make a wrapper for the data 00314 */ 00315 hDdePack = UserGlobalAlloc(GMEM_DDESHARE | GMEM_FIXED, 00316 sizeof(DDEPACK)); 00317 pDdePack = (PDDEPACK)hDdePack; 00318 if (pDdePack == NULL) { 00319 RIPMSG0(RIP_WARNING, "_ClientCopyDDEOut1:Couldn't allocate DDEPACK"); 00320 return (NULL); 00321 } 00322 *pDdePack = pi->DdePack; 00323 } 00324 00325 if (pi->cbDirect) { 00326 pi->hDirect = UserGlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, pi->cbDirect); 00327 if (pi->hDirect == NULL) { 00328 RIPMSG0(RIP_WARNING, "_ClientCopyDDEOut1:Couldn't allocate hDirect"); 00329 if (hDdePack) { 00330 UserGlobalFree(hDdePack); 00331 } 00332 return (NULL); 00333 } 00334 00335 USERGLOBALLOCK(pi->hDirect, pi->pDirect); 00336 UserAssert(pi->pDirect); 00337 00338 // fixup packed data reference to direct data 00339 00340 if (pDdePack != NULL) { 00341 if (pi->flags & XS_LOHANDLE) { 00342 pDdePack->uiLo = HandleToUlong(pi->hDirect); 00343 UserAssert((ULONG_PTR)pDdePack->uiLo == (ULONG_PTR)pi->hDirect); 00344 } else if (pi->flags & XS_HIHANDLE) { 00345 pDdePack->uiHi = HandleToUlong(pi->hDirect); 00346 UserAssert((ULONG_PTR)pDdePack->uiHi == (ULONG_PTR)pi->hDirect); 00347 } 00348 } 00349 00350 if (pi->cbIndirect) { 00351 pi->hIndirect = UserGlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, 00352 pi->cbIndirect); 00353 if (pi->hIndirect == NULL) { 00354 RIPMSG0(RIP_WARNING, "_ClientCopyDDEOut1:Couldn't allocate hIndirect"); 00355 USERGLOBALUNLOCK(pi->hDirect); 00356 UserGlobalFree(pi->hDirect); 00357 if (hDdePack) { 00358 UserGlobalFree(hDdePack); 00359 } 00360 return (NULL); 00361 } 00362 USERGLOBALLOCK(pi->hIndirect, pi->pIndirect); 00363 UserAssert(pi->pIndirect); 00364 } 00365 } 00366 00367 if (hDdePack) { 00368 return (hDdePack); 00369 } else { 00370 return (pi->hDirect); 00371 } 00372 } 00373 00374 00375 00376 /* 00377 * Fixes up internal poniters after thunk copy and unlocks handles. 00378 */ 00379 BOOL _ClientCopyDDEOut2( 00380 PINTDDEINFO pi) 00381 { 00382 BOOL fSuccess = TRUE; 00383 /* 00384 * done with copies - now fixup indirect references 00385 */ 00386 if (pi->hIndirect) { 00387 PDDE_DATA pDdeData = (PDDE_DATA)pi->pDirect; 00388 00389 switch (pDdeData->wFmt) { 00390 case CF_BITMAP: 00391 case CF_DSPBITMAP: 00392 case CF_PALETTE: 00393 pDdeData->Data = (ULONG_PTR)pi->hIndirect; 00394 fSuccess = (BOOL)pDdeData->Data; 00395 break; 00396 00397 case CF_METAFILEPICT: 00398 case CF_DSPMETAFILEPICT: 00399 pDdeData->Data = (ULONG_PTR)GdiCreateLocalMetaFilePict(pi->hIndirect); 00400 fSuccess = (BOOL)pDdeData->Data; 00401 break; 00402 00403 case CF_DIB: 00404 pDdeData->Data = (ULONG_PTR)pi->hIndirect; 00405 fSuccess = (BOOL)pDdeData->Data; 00406 USERGLOBALUNLOCK(pi->hIndirect); 00407 break; 00408 00409 case CF_ENHMETAFILE: 00410 case CF_DSPENHMETAFILE: 00411 pDdeData->Data = (ULONG_PTR)GdiCreateLocalEnhMetaFile(pi->hIndirect); 00412 fSuccess = (BOOL)pDdeData->Data; 00413 break; 00414 00415 default: 00416 RIPMSG0(RIP_WARNING, "_ClientCopyDDEOut2:Unknown format w/indirect data."); 00417 fSuccess = FALSE; 00418 USERGLOBALUNLOCK(pi->hIndirect); 00419 } 00420 } 00421 00422 UserAssert(pi->hDirect); // if its null, we didn't need to call this function. 00423 USERGLOBALUNLOCK(pi->hDirect); 00424 if (pi->flags & XS_EXECUTE) { 00425 /* 00426 * Its possible that in RAW DDE cases where the app allocated the 00427 * execute data as non-moveable, we have a different hDirect 00428 * than we started with. This needs to be noted and passed 00429 * back to the server. (Very RARE case) 00430 */ 00431 FixupDdeExecuteIfNecessary(&pi->hDirect, 00432 pi->flags & XS_UNICODE); 00433 } 00434 return fSuccess; 00435 } 00436 00437 00438 00439 /* 00440 * This routine is called by the tracking layer when it frees DDE objects 00441 * on behalf of a client. This cleans up the LOCAL objects associated 00442 * with the DDE objects. It should NOT remove truely global objects such 00443 * as bitmaps or palettes except in the XS_DUMPMSG case which is for 00444 * faked Posts. 00445 */ 00446 00447 #if DBG 00448 /* 00449 * Help track down a bug where I suspect the xxxFreeListFree is 00450 * freeing a handle already freed by some other means which has 00451 * since been reallocated and is trashing the client heap. (SAS) 00452 */ 00453 HANDLE DDEHandleLastFreed = 0; 00454 #endif 00455 00456 BOOL _ClientFreeDDEHandle( 00457 HANDLE hDDE, 00458 DWORD flags) 00459 { 00460 PDDEPACK pDdePack; 00461 HANDLE hNew; 00462 00463 if (flags & XS_PACKED) { 00464 pDdePack = (PDDEPACK)hDDE; 00465 if (pDdePack == NULL) { 00466 return (FALSE); 00467 } 00468 if (flags & XS_LOHANDLE) { 00469 hNew = (HANDLE)pDdePack->uiLo; 00470 } else { 00471 hNew = (HANDLE)pDdePack->uiHi; 00472 00473 } 00474 WOWGLOBALFREE(hDDE); 00475 hDDE = hNew; 00476 00477 } 00478 00479 /* 00480 * Do a range check and call GlobalFlags to validate, just to prevent heap checking 00481 * from complaining during the GlobalSize call. 00482 * Is this leaking atoms?? 00483 */ 00484 if ((hDDE <= (HANDLE)0xFFFF) 00485 || (GlobalFlags(hDDE) == GMEM_INVALID_HANDLE) 00486 || !GlobalSize(hDDE)) { 00487 /* 00488 * There may be cases where apps improperly freed stuff 00489 * when they shouldn't have so make sure this handle 00490 * is valid by the time it gets here. 00491 * 00492 * See SvSpontAdvise; it posts a message with an atom in uiHi. Then from _PostMessage 00493 * in the kernel side, we might end up here. So it's not only for apps... 00494 */ 00495 return(FALSE); 00496 } 00497 00498 if (flags & XS_DUMPMSG) { 00499 if (flags & XS_PACKED) { 00500 if (!IS_PTR(hNew)) { 00501 GlobalDeleteAtom(LOWORD((ULONG_PTR)hNew)); 00502 if (!(flags & XS_DATA)) { 00503 return(TRUE); // ACK 00504 } 00505 } 00506 } else { 00507 if (!(flags & XS_EXECUTE)) { 00508 GlobalDeleteAtom(LOWORD((ULONG_PTR)hDDE)); // REQUEST, UNADVISE 00509 return(TRUE); 00510 } 00511 } 00512 } 00513 if (flags & XS_DATA) { 00514 // POKE, DATA 00515 #if DBG 00516 DDEHandleLastFreed = hDDE; 00517 #endif 00518 FreeDDEData(hDDE, 00519 (flags & XS_DUMPMSG) ? FALSE : TRUE, // fIgnorefRelease 00520 (flags & XS_DUMPMSG) ? TRUE : FALSE); // fDestroyTruelyGlobalObjects 00521 } else { 00522 // ADVISE, EXECUTE 00523 #if DBG 00524 DDEHandleLastFreed = hDDE; 00525 #endif 00526 WOWGLOBALFREE(hDDE); // covers ADVISE case (fmt but no data) 00527 } 00528 return (TRUE); 00529 } 00530 00531 00532 DWORD _ClientGetDDEFlags( 00533 HANDLE hDDE, 00534 DWORD flags) 00535 { 00536 PDDEPACK pDdePack; 00537 PWORD pw; 00538 HANDLE hData; 00539 DWORD retval = 0; 00540 00541 pDdePack = (PDDEPACK)hDDE; 00542 if (pDdePack == NULL) { 00543 return (0); 00544 } 00545 00546 if (flags & XS_DATA) { 00547 if (pDdePack->uiLo) { 00548 hData = (HANDLE)pDdePack->uiLo; 00549 USERGLOBALLOCK(hData, pw); 00550 if (pw != NULL) { 00551 retval = (DWORD)*pw; // first word is hData is wStatus 00552 USERGLOBALUNLOCK(hData); 00553 } 00554 } 00555 } else { 00556 retval = (DWORD)pDdePack->uiLo; 00557 } 00558 00559 return (retval); 00560 } 00561 00562 00563 LPARAM APIENTRY PackDDElParam( 00564 UINT msg, 00565 UINT_PTR uiLo, 00566 UINT_PTR uiHi) 00567 { 00568 PDDEPACK pDdePack; 00569 HANDLE h; 00570 00571 switch (msg) { 00572 case WM_DDE_EXECUTE: 00573 return((LPARAM)uiHi); 00574 00575 case WM_DDE_ACK: 00576 case WM_DDE_ADVISE: 00577 case WM_DDE_DATA: 00578 case WM_DDE_POKE: 00579 h = UserGlobalAlloc(GMEM_DDESHARE | GMEM_FIXED, sizeof(DDEPACK)); 00580 pDdePack = (PDDEPACK)h; 00581 if (pDdePack == NULL) { 00582 return(0); 00583 } 00584 pDdePack->uiLo = uiLo; 00585 pDdePack->uiHi = uiHi; 00586 return((LPARAM)h); 00587 00588 default: 00589 return(MAKELONG((WORD)uiLo, (WORD)uiHi)); 00590 } 00591 } 00592 00593 00594 00595 BOOL APIENTRY UnpackDDElParam( 00596 UINT msg, 00597 LPARAM lParam, 00598 PUINT_PTR puiLo, 00599 PUINT_PTR puiHi) 00600 { 00601 PDDEPACK pDdePack; 00602 00603 switch (msg) { 00604 case WM_DDE_EXECUTE: 00605 if (puiLo != NULL) { 00606 *puiLo = 0L; 00607 } 00608 if (puiHi != NULL) { 00609 *puiHi = (UINT_PTR)lParam; 00610 } 00611 return(TRUE); 00612 00613 case WM_DDE_ACK: 00614 case WM_DDE_ADVISE: 00615 case WM_DDE_DATA: 00616 case WM_DDE_POKE: 00617 pDdePack = (PDDEPACK)lParam; 00618 if (pDdePack == NULL || !GlobalHandle(pDdePack)) { 00619 return(FALSE); 00620 } 00621 if (puiLo != NULL) { 00622 *puiLo = pDdePack->uiLo; 00623 } 00624 if (puiHi != NULL) { 00625 *puiHi = pDdePack->uiHi; 00626 } 00627 return(TRUE); 00628 00629 default: 00630 if (puiLo != NULL) { 00631 *puiLo = (UINT)LOWORD(lParam); 00632 } 00633 if (puiHi != NULL) { 00634 *puiHi = (UINT)HIWORD(lParam); 00635 } 00636 return(TRUE); 00637 } 00638 } 00639 00640 00641 00642 BOOL APIENTRY FreeDDElParam( 00643 UINT msg, 00644 LPARAM lParam) 00645 { 00646 switch (msg) { 00647 case WM_DDE_ACK: 00648 case WM_DDE_ADVISE: 00649 case WM_DDE_DATA: 00650 case WM_DDE_POKE: 00651 /* 00652 * Do a range check and call GlobalFlags to validate, 00653 * just to prevent heap checking from complaining 00654 */ 00655 if ((lParam > (LPARAM)0xFFFF) && GlobalFlags((HANDLE)lParam) != GMEM_INVALID_HANDLE) { 00656 if (GlobalHandle((HANDLE)lParam)) 00657 return(UserGlobalFree((HANDLE)lParam) == NULL); 00658 } 00659 00660 default: 00661 return(TRUE); 00662 } 00663 } 00664 00665 00666 LPARAM APIENTRY ReuseDDElParam( 00667 LPARAM lParam, 00668 UINT msgIn, 00669 UINT msgOut, 00670 UINT_PTR uiLo, 00671 UINT_PTR uiHi) 00672 { 00673 PDDEPACK pDdePack; 00674 00675 switch (msgIn) { 00676 case WM_DDE_ACK: 00677 case WM_DDE_DATA: 00678 case WM_DDE_POKE: 00679 case WM_DDE_ADVISE: 00680 // 00681 // Incoming message was packed... 00682 // 00683 switch (msgOut) { 00684 case WM_DDE_EXECUTE: 00685 FreeDDElParam(msgIn, lParam); 00686 return((LPARAM)uiHi); 00687 00688 case WM_DDE_ACK: 00689 case WM_DDE_ADVISE: 00690 case WM_DDE_DATA: 00691 case WM_DDE_POKE: 00692 /* 00693 * This must be a valid handle 00694 */ 00695 UserAssert(GlobalFlags((HANDLE)lParam) != GMEM_INVALID_HANDLE); 00696 UserAssert(GlobalSize((HANDLE)lParam) == sizeof(DDEPACK)); 00697 // 00698 // Actual cases where lParam can be reused. 00699 // 00700 pDdePack = (PDDEPACK)lParam; 00701 if (pDdePack == NULL) { 00702 return(0); // the only error case 00703 } 00704 pDdePack->uiLo = uiLo; 00705 pDdePack->uiHi = uiHi; 00706 return(lParam); 00707 00708 00709 default: 00710 FreeDDElParam(msgIn, lParam); 00711 return(MAKELONG((WORD)uiLo, (WORD)uiHi)); 00712 } 00713 00714 default: 00715 // 00716 // Incoming message was not packed ==> PackDDElParam() 00717 // 00718 return(PackDDElParam(msgOut, uiLo, uiHi)); 00719 } 00720 }

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