test: wow.c Source File

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

# wow.c

Go to the documentation of this file.

    00001 /****************************** Module Header ******************************\
    00002 * Module Name: wow.c
    00003 *
    00004 * Copyright (c) 1985 - 1999, Microsoft Corporation
    00005 *
    00006 * This module contains shared code between USER32 and USER16
    00007 * No New CODE should be added to this file, unless its shared
    00008 * with USER16.
    00009 *
    00010 * History:
    00011 * 29-DEC-93 NanduriR      shared user32/user16 code.
    00012 \***************************************************************************/
    00013
    00014 #include "precomp.h"
    00015 #pragma hdrstop
    00016
    00017
    00018 /***************************************************************************\
    00019 * ValidateHwnd
    00020 *
    00021 * Verify that the handle is valid.  If the handle is invalid or access
    00022 * cannot be granted fail.
    00023 *
    00024 * History:
    00025 * 03-18-92 DarrinM      Created from pieces of misc server-side funcs.
    00026 \***************************************************************************/
    00027
    00028 PWND FASTCALL ValidateHwnd(
    00029     HWND hwnd)
    00030 {
    00031     PCLIENTINFO pci = GetClientInfo();
    00032
    00033     /*
    00034      * Attempt fast window validation
    00035      */
    00036     if (hwnd != NULL && hwnd == pci->CallbackWnd.hwnd) {
    00037         return pci->CallbackWnd.pwnd;
    00038     }
    00039
    00040     /*
    00041      * Validate the handle is of the proper type.
    00042      */
    00043     return HMValidateHandle(hwnd, TYPE_WINDOW);
    00044 }
    00045
    00046
    00047 PWND FASTCALL ValidateHwndNoRip(
    00048     HWND hwnd)
    00049 {
    00050     PCLIENTINFO pci = GetClientInfo();
    00051
    00052     /*
    00053      * Attempt fast window validation
    00054      */
    00055     if (hwnd != NULL && hwnd == pci->CallbackWnd.hwnd) {
    00056         return pci->CallbackWnd.pwnd;
    00057     }
    00058
    00059     /*
    00060      * Validate the handle is of the proper type.
    00061      */
    00062     return HMValidateHandleNoRip(hwnd, TYPE_WINDOW);
    00063 }
    00064
    00065
    00066
    00067 int WINAPI GetClassNameA(
    00068     HWND hwnd,
    00069     LPSTR lpClassName,
    00070     int nMaxCount)
    00071 {
    00072     PCLS pcls;
    00073     LPSTR lpszClassNameSrc;
    00074     PWND pwnd;
    00075     int cchSrc;
    00076
    00077     pwnd = ValidateHwnd(hwnd);
    00078
    00079     if (pwnd == NULL)
    00080         return FALSE;
    00081
    00082     try {
    00083         if (nMaxCount != 0) {
    00084             pcls = (PCLS)REBASEALWAYS(pwnd, pcls);
    00085             lpszClassNameSrc = REBASEPTR(pwnd, pcls->lpszAnsiClassName);
    00086             cchSrc = lstrlenA(lpszClassNameSrc);
    00087             nMaxCount = min(cchSrc, nMaxCount - 1);
    00088             RtlCopyMemory(lpClassName, lpszClassNameSrc, nMaxCount);
    00089             lpClassName[nMaxCount] = '\0';
    00090         }
    00091     } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
    00092         nMaxCount = 0;
    00093     }
    00094
    00095     return nMaxCount;
    00096 }
    00097
    00098 /***************************************************************************\
    00099 * _GetDesktopWindow (API)
    00100 *
    00101 *
    00102 *
    00103 * History:
    00104 * 11-07-90 darrinm      Implemented.
    00105 \***************************************************************************/
    00106
    00107 PWND _GetDesktopWindow(void)
    00108 {
    00109     PCLIENTINFO pci;
    00110
    00111     ConnectIfNecessary();
    00112
    00113     pci = GetClientInfo();
    00114     return (PWND)((KERNEL_ULONG_PTR)pci->pDeskInfo->spwnd -
    00115             pci->ulClientDelta);
    00116 }
    00117
    00118
    00119
    00120 HWND GetDesktopWindow(void)
    00121 {
    00122     PWND        pwnd;
    00123     PCLIENTINFO pci;
    00124
    00125     pwnd = _GetDesktopWindow();
    00126
    00127     pci = GetClientInfo();
    00128
    00129     /*
    00130      * validate the parent window's handle if a restricted process
    00131      */
    00132     if (pci && (pci->dwTIFlags & TIF_RESTRICTED)) {
    00133         if (ValidateHwnd(HW(pwnd)) == NULL) {
    00134             return NULL;
    00135         }
    00136     }
    00137     return HW(pwnd);
    00138 }
    00139
    00140
    00141 PWND _GetDlgItem(
    00142     PWND pwnd,
    00143     int id)
    00144 {
    00145     if (pwnd != NULL) {
    00146         pwnd = REBASEPWND(pwnd, spwndChild);
    00147         while (pwnd != NULL) {
    00148             if (PtrToLong(pwnd->spmenu) == id)
    00149                 break;
    00150             pwnd = REBASEPWND(pwnd, spwndNext);
    00151         }
    00152     }
    00153
    00154     return pwnd;
    00155 }
    00156
    00157
    00158 HWND GetDlgItem(
    00159     HWND hwnd,
    00160     int id)
    00161 {
    00162     PWND pwnd;
    00163     HWND hwndRet;
    00164
    00165     pwnd = ValidateHwnd(hwnd);
    00166     if (pwnd == NULL)
    00167         return NULL;
    00168
    00169     pwnd = _GetDlgItem(pwnd, id);
    00170
    00171     hwndRet = HW(pwnd);
    00172
    00173     if (hwndRet == (HWND)0)
    00174         RIPERR0(ERROR_CONTROL_ID_NOT_FOUND, RIP_VERBOSE, "");
    00175
    00176     return hwndRet;
    00177 }
    00178
    00179
    00180 HMENU GetMenu(
    00181     HWND hwnd)
    00182 {
    00183     PWND pwnd;
    00184     PMENU pmenu;
    00185
    00186     pwnd = ValidateHwnd(hwnd);
    00187
    00188     if (pwnd == NULL)
    00189         return 0;
    00190
    00191     /*
    00192      * Some ill-behaved apps use GetMenu to get the child id, so
    00193      * only map to the handle for non-child windows.
    00194      */
    00195     if (!TestwndChild(pwnd)) {
    00196         pmenu = REBASE(pwnd, spmenu);
    00197         return (HMENU)PtoH(pmenu);
    00198     } else {
    00199         return (HMENU)pwnd->spmenu;
    00200     }
    00201 }
    00202
    00203
    00204 /***************************************************************************\
    00205 * GetMenuItemCount
    00206 *
    00207 * Returns a count of the number of items in the menu. Returns -1 if
    00208 * invalid menu.
    00209 *
    00210 * History:
    00211 \***************************************************************************/
    00212
    00213 int GetMenuItemCount(
    00214     HMENU hMenu)
    00215 {
    00216     PMENU pMenu;
    00217
    00218     pMenu = VALIDATEHMENU(hMenu);
    00219
    00220     if (pMenu == NULL)
    00221         return -1;
    00222
    00223     return pMenu->cItems;
    00224 }
    00225
    00226 /***************************************************************************\
    00227 * GetMenuItemID
    00228 *
    00229 * Return the ID of a menu item at the specified position.
    00230 *
    00231 * History:
    00232 \***************************************************************************/
    00233
    00234 UINT GetMenuItemID(
    00235     HMENU hMenu,
    00236     int nPos)
    00237 {
    00238     PMENU pMenu;
    00239     PITEM pItem;
    00240
    00241     pMenu = VALIDATEHMENU(hMenu);
    00242
    00243     if (pMenu == NULL)
    00244         return (UINT)-1;
    00245
    00246     /*
    00247      * If the position is valid and the item is not a popup, get the ID
    00248      * Don't allow negative indexes, because that'll cause an access violation.
    00249      */
    00250     if (nPos < (int)pMenu->cItems && nPos >= 0) {
    00251         pItem = &((PITEM)REBASEALWAYS(pMenu, rgItems))[nPos];
    00252         if (pItem->spSubMenu == NULL)
    00253             return pItem->wID;
    00254     }
    00255
    00256     return (UINT)-1;
    00257 }
    00258
    00259
    00260 UINT GetMenuState(
    00261     HMENU hMenu,
    00262     UINT uId,
    00263     UINT uFlags)
    00264 {
    00265     PMENU pMenu;
    00266
    00267     pMenu = VALIDATEHMENU(hMenu);
    00268
    00269     if (pMenu == NULL || (uFlags & ~MF_VALID) != 0) {
    00270         return (UINT)-1;
    00271     }
    00272
    00273     return _GetMenuState(pMenu, uId, uFlags);
    00274 }
    00275
    00276
    00277 BOOL IsWindow(
    00278     HWND hwnd)
    00279 {
    00280     PWND pwnd;
    00281
    00282     /*
    00283      * Validate the handle is of type window
    00284      */
    00285     pwnd = ValidateHwndNoRip(hwnd);
    00286
    00287     /*
    00288      * And validate this handle is valid for this desktop by trying to read it
    00289      */
    00290     if (pwnd != NULL) {
    00291         try {
    00292             if (pwnd->fnid & FNID_DELETED_BIT) {
    00293                 pwnd = 0;
    00294             }
    00295         } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
    00296             RIPMSG1(RIP_WARNING, "IsWindow: Window %#p not of this desktop",
    00297                     pwnd);
    00298             pwnd = 0;
    00299         }
    00300     }
    00301     return !!pwnd;
    00302 }
    00303
    00304
    00305 HWND GetWindow(
    00306     HWND hwnd,
    00307     UINT wCmd)
    00308 {
    00309     PWND pwnd;
    00310
    00311     pwnd = ValidateHwnd(hwnd);
    00312     if (pwnd == NULL)
    00313         return NULL;
    00314
    00315     pwnd = _GetWindow(pwnd, wCmd);
    00316     return HW(pwnd);
    00317 }
    00318
    00319 HWND GetParent(
    00320     HWND hwnd)
    00321 {
    00322     PWND        pwnd;
    00323     PCLIENTINFO pci;
    00324
    00325     pwnd = ValidateHwnd(hwnd);
    00326     if (pwnd == NULL)
    00327         return NULL;
    00328
    00329     try {
    00330         pwnd = _GetParent(pwnd);
    00331         hwnd = HW(pwnd);
    00332     } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
    00333         hwnd = NULL;
    00334     }
    00335
    00336     pci = GetClientInfo();
    00337
    00338     /*
    00339      * validate the parent window's handle if a restricted process
    00340      */
    00341     if (pci && (pci->dwTIFlags & TIF_RESTRICTED)) {
    00342         if (ValidateHwnd(hwnd) == NULL) {
    00343             return NULL;
    00344         }
    00345     }
    00346
    00347     return hwnd;
    00348 }
    00349
    00350 HMENU GetSubMenu(
    00351     HMENU hMenu,
    00352     int nPos)
    00353 {
    00354     PMENU pMenu;
    00355
    00356     pMenu = VALIDATEHMENU(hMenu);
    00357
    00358     if (pMenu == NULL)
    00359         return 0;
    00360
    00361     pMenu = _GetSubMenu(pMenu, nPos);
    00362     return (HMENU)PtoH(pMenu);
    00363 }
    00364
    00365
    00366 DWORD GetSysColor(
    00367     int nIndex)
    00368 {
    00369
    00370     /*
    00371      * Currently we don't do client side checks because they do not really
    00372      * make sense;  someone can read the data even with the checks.  We
    00373      * leave in the attribute values in case we want to move these values
    00374      * back to the server side someday
    00375      */
    00376 #ifdef ENABLE_CLIENTSIDE_ACCESSCHECK
    00377     /*
    00378      * Make sure we have access to the system colors.
    00379      */
    00380     if (!(gamWinSta & WINSTA_READATTRIBUTES)) {
    00381         return 0;
    00382     }
    00383 #endif
    00384
    00385     /*
    00386      * Return 0 if the index is out of range.
    00387      */
    00388     if (nIndex < 0 || nIndex >= COLOR_MAX) {
    00389         RIPERR1(ERROR_INVALID_PARAMETER,
    00390                 RIP_WARNING,
    00391                 "Invalid parameter \"nIndex\" (%ld) to GetSysColor",
    00392                 nIndex);
    00393
    00394         return 0;
    00395     }
    00396
    00397     return (gpsi->argbSystem[nIndex]);
    00398 }
    00399
    00400
    00401 int GetSystemMetrics(
    00402     int index)
    00403 {
    00404     ConnectIfNecessary();
    00405
    00406     /*
    00407      * check first for values that are out of the 'aiSysMet' array
    00408      */
    00409     switch (index) {
    00410
    00411     case SM_REMOTESESSION:
    00412         return ISREMOTESESSION();
    00413     }
    00414
    00415     if ((index < 0) || (index >= SM_CMETRICS))
    00416         return 0;
    00417
    00418     switch (index) {
    00419     case SM_DBCSENABLED:
    00420 #ifdef FE_SB
    00421         return TEST_BOOL_FLAG(gpsi->wSRVIFlags, SRVIF_DBCS);
    00422 #else
    00423         return FALSE;
    00424 #endif
    00425     case SM_IMMENABLED:
    00426 #ifdef FE_IME
    00427         return TEST_BOOL_FLAG(gpsi->wSRVIFlags, SRVIF_IME);
    00428 #else
    00429         return FALSE;
    00430 #endif
    00431
    00432     case SM_MIDEASTENABLED:
    00433         return TEST_BOOL_FLAG(gpsi->wSRVIFlags, SRVIF_MIDEAST);
    00434     }
    00435
    00436     if (GetClientInfo()->dwExpWinVer < VER40) {
    00437         /*
    00438          * SCROLL BAR
    00439          * before 4.0, the scroll bars and the border overlapped by a pixel.  Many apps
    00440          * rely on this overlap when they compute dimensions.  Now, in 4.0, this pixel
    00441          * overlap is no longer there.  So for old apps, we lie and pretend the overlap
    00442          * is there by making the scroll bar widths one bigger.
    00443          *
    00444          * DLGFRAME
    00445          * In Win3.1, SM_CXDLGFRAME & SM_CYDLGFRAME were border space MINUS 1
    00446          * In Win4.0, they are border space
    00447          *
    00448          * CAPTION
    00449          * In Win3.1, SM_CYCAPTION was the caption height PLUS 1
    00450          * In Win4.0, SM_CYCAPTION is the caption height
    00451          *
    00452          * MENU
    00453          * In Win3.1, SM_CYMENU was the menu height MINUS 1
    00454          * In Win4.0, SM_CYMENU is the menu height
    00455          */
    00456
    00457         switch (index) {
    00458
    00459         case SM_CXDLGFRAME:
    00460         case SM_CYDLGFRAME:
    00461         case SM_CYMENU:
    00462         case SM_CYFULLSCREEN:
    00463             return (gpsi->aiSysMet)[index] - 1;
    00464
    00465         case SM_CYCAPTION:
    00466         case SM_CXVSCROLL:
    00467         case SM_CYHSCROLL:
    00468             return (gpsi->aiSysMet)[index] + 1;
    00469         }
    00470     }
    00471
    00472     return gpsi->aiSysMet[index];
    00473 }
    00474
    00475 /***************************************************************************\
    00476 * GetTopWindow (API)
    00477 *
    00478 * This poorly named API should really be called 'GetFirstChild', which is
    00479 * what it does.
    00480 *
    00481 * History:
    00482 * 11-12-90 darrinm      Ported.
    00483 * 02-19-91 JimA         Added enum access check
    00484 * 05-04-02 DarrinM      Removed enum access check and moved to USERRTL.DLL
    00485 \***************************************************************************/
    00486
    00487 HWND GetTopWindow(
    00488     HWND hwnd)
    00489 {
    00490     PWND pwnd;
    00491
    00492     /*
    00493      * Allow a NULL hwnd to go through here.
    00494      */
    00495     if (hwnd == NULL) {
    00496         pwnd = _GetDesktopWindow();
    00497     } else {
    00498         pwnd = ValidateHwnd(hwnd);
    00499     }
    00500     if (pwnd == NULL)
    00501         return NULL;
    00502
    00503     pwnd = REBASEPWND(pwnd, spwndChild);
    00504     return HW(pwnd);
    00505 }
    00506
    00507
    00508 BOOL IsChild(
    00509     HWND hwndParent,
    00510     HWND hwnd)
    00511 {
    00512     PWND pwnd, pwndParent;
    00513
    00514     pwnd = ValidateHwnd(hwnd);
    00515     if (pwnd == NULL)
    00516         return FALSE;
    00517
    00518     pwndParent = ValidateHwnd(hwndParent);
    00519     if (pwndParent == NULL)
    00520         return FALSE;
    00521
    00522     return _IsChild(pwndParent, pwnd);
    00523 }
    00524
    00525 BOOL IsIconic(
    00526     HWND hwnd)
    00527 {
    00528     PWND pwnd;
    00529
    00530     pwnd = ValidateHwnd(hwnd);
    00531
    00532     if (pwnd == NULL)
    00533         return FALSE;
    00534
    00535     return _IsIconic(pwnd);
    00536 }
    00537
    00538 BOOL IsWindowEnabled(
    00539     HWND hwnd)
    00540 {
    00541     PWND pwnd;
    00542
    00543     pwnd = ValidateHwnd(hwnd);
    00544
    00545     if (pwnd == NULL)
    00546         return FALSE;
    00547
    00548     return _IsWindowEnabled(pwnd);
    00549 }
    00550
    00551 BOOL IsWindowVisible(
    00552     HWND hwnd)
    00553 {
    00554     PWND pwnd;
    00555     BOOL bRet;
    00556
    00557     pwnd = ValidateHwnd(hwnd);
    00558
    00559     /*
    00560      * We have have to try - except this call because there is no
    00561      * synchronization on the window structure on the client side.
    00562      * If the window is deleted after it is validated then we can
    00563      * fault so we catch that on return that the window is not
    00564      * visible.  As soon as this API returns there is no guarentee
    00565      * the return is still valid in a muli-tasking environment.
    00566      */
    00567     try {
    00568         if (pwnd == NULL) {
    00569             bRet = FALSE;
    00570         } else {
    00571             bRet = _IsWindowVisible(pwnd);
    00572         }
    00573     } except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
    00574         bRet = FALSE;
    00575     }
    00576
    00577     return bRet;
    00578 }
    00579
    00580 BOOL IsZoomed(
    00581     HWND hwnd)
    00582 {
    00583     PWND pwnd;
    00584
    00585     pwnd = ValidateHwnd(hwnd);
    00586
    00587     if (pwnd == NULL)
    00588         return FALSE;
    00589
    00590     return _IsZoomed(pwnd);
    00591 }
    00592
    00593 BOOL ClientToScreen(
    00594     HWND hwnd,
    00595     LPPOINT ppoint)
    00596 {
    00597     PWND pwnd;
    00598
    00599     pwnd = ValidateHwnd(hwnd);
    00600
    00601     if (pwnd == NULL)
    00602         return FALSE;
    00603
    00604     _ClientToScreen(pwnd, ppoint);
    00605     return TRUE;
    00606 }
    00607
    00608 BOOL GetClientRect(
    00609     HWND   hwnd,
    00610     LPRECT prect)
    00611 {
    00612     PWND pwnd;
    00613
    00614     pwnd = ValidateHwnd(hwnd);
    00615
    00616     if (pwnd == NULL)
    00617         return FALSE;
    00618
    00619     _GetClientRect(pwnd, prect);
    00620     return TRUE;
    00621 }
    00622
    00623
    00624 BOOL GetCursorPos(
    00625     LPPOINT lpPoint)
    00626 {
    00627 #ifdef REDIRECTION
    00628     PCLIENTINFO pci;
    00629 #endif // REDIRECTION
    00630
    00631     /*
    00632      * Blow it off if the caller doesn't have the proper access rights
    00633      */
    00634 #ifdef ENABLE_CLIENTSIDE_ACCESSCHECK
    00635     if (!(gamWinSta & WINSTA_READATTRIBUTES)) {
    00636         lpPoint->x = 0;
    00637         lpPoint->y = 0;
    00638         return FALSE;
    00639     }
    00640 #endif
    00641
    00642     *lpPoint = gpsi->ptCursor;
    00643
    00644 #ifdef REDIRECTION
    00645     pci = GetClientInfo();
    00646
    00647     if (pci != NULL && pci->pDeskInfo != NULL && IsHooked(pci, WHF_CBT)) {
    00648         NtUserCallOneParam((ULONG_PTR)lpPoint, SFI_XXXGETCURSORPOS);
    00649     }
    00650 #endif // REDIRECTION
    00651
    00652     return TRUE;
    00653 }
    00654
    00655 BOOL GetWindowRect(
    00656     HWND hwnd,
    00657     LPRECT prect)
    00658 {
    00659     PWND pwnd;
    00660
    00661     pwnd = ValidateHwnd(hwnd);
    00662
    00663     if (pwnd == NULL)
    00664         return FALSE;
    00665
    00666     _GetWindowRect(pwnd, prect);
    00667     return TRUE;
    00668 }
    00669
    00670 BOOL ScreenToClient(
    00671     HWND hwnd,
    00672     LPPOINT ppoint)
    00673 {
    00674     PWND pwnd;
    00675
    00676     pwnd = ValidateHwnd(hwnd);
    00677
    00678     if (pwnd == NULL)
    00679         return FALSE;
    00680
    00681     _ScreenToClient(pwnd, ppoint);
    00682     return TRUE;
    00683 }
    00684
    00685 BOOL EnableMenuItem(
    00686     HMENU hMenu,
    00687     UINT uIDEnableItem,
    00688     UINT uEnable)
    00689 {
    00690     PMENU pMenu;
    00691     PITEM pItem;
    00692
    00693     pMenu = VALIDATEHMENU(hMenu);
    00694     if (pMenu == NULL) {
    00695         return (BOOL)-1;
    00696     }
    00697
    00698     /*
    00699      * Get a pointer the the menu item
    00700      */
    00701     if ((pItem = MNLookUpItem(pMenu, uIDEnableItem, (BOOL) (uEnable & MF_BYPOSITION), NULL)) == NULL)
    00702         return (DWORD)-1;
    00703
    00704     /*
    00705      * If the item is already in the state we're
    00706      * trying to set, just return.
    00707      */
    00708     if ((pItem->fState & MFS_GRAYED) ==
    00709             (uEnable & MFS_GRAYED)) {
    00710         return pItem->fState & MFS_GRAYED;
    00711     }
    00712
    00713     return NtUserEnableMenuItem(hMenu, uIDEnableItem, uEnable);
    00714 }
    00715
    00716 /***************************************************************************\
    00717 * CallNextHookEx
    00718 *
    00719 * This routine is called to call the next hook in the hook chain.
    00720 *
    00721 * 05-09-91 ScottLu Created.
    00722 \***************************************************************************/
    00723
    00724 LRESULT WINAPI CallNextHookEx(
    00725     HHOOK hhk,
    00726     int nCode,
    00727     WPARAM wParam,
    00728     LPARAM lParam)
    00729 {
    00730     LRESULT nRet;
    00731     BOOL  bAnsi;
    00732     DWORD dwHookCurrent;
    00733     PCLIENTINFO pci;
    00734     ULONG_PTR dwHookData;
    00735     ULONG_PTR dwFlags;
    00736
    00737     DBG_UNREFERENCED_PARAMETER(hhk);
    00738
    00739     ConnectIfNecessary();
    00740
    00741     pci = GetClientInfo();
    00742     dwHookCurrent = pci->dwHookCurrent;
    00743     bAnsi = LOWORD(dwHookCurrent);
    00744
    00745     /*
    00746      * If this is the last hook in the hook chain then return 0; we're done
    00747      */
    00748     UserAssert(pci->phkCurrent);
    00749     if (PhkNextValid((PHOOK)((KERNEL_ULONG_PTR)pci->phkCurrent - pci->ulClientDelta)) == NULL) {
    00750         return 0;
    00751     }
    00752
    00753     switch ((INT)(SHORT)HIWORD(dwHookCurrent)) {
    00754     case WH_CALLWNDPROC:
    00755     case WH_CALLWNDPROCRET:
    00756         /*
    00757          * This is the hardest of the hooks because we need to thunk through
    00758          * the message hooks in order to deal with synchronously sent messages
    00759          * that point to structures - to get the structures passed across
    00760          * alright, etc.
    00761          *
    00762          * This will call a special kernel-side routine that'll rebundle the
    00763          * arguments and call the hook in the right format.
    00764          *
    00765          * Currently, the message thunk callbacks to the client-side don't take
    00766          * enough parameters to pass wParam (which == fInterThread send msg).
    00767          * To do this, save the state of wParam in the CLIENTINFO structure.
    00768          */
    00769         dwFlags = KERNEL_ULONG_PTR_TO_ULONG_PTR(pci->CI_flags) & CI_INTERTHREAD_HOOK;
    00770         dwHookData = KERNEL_ULONG_PTR_TO_ULONG_PTR(pci->dwHookData);
    00771         if (wParam) {
    00772             pci->CI_flags |= CI_INTERTHREAD_HOOK;
    00773         } else {
    00774             pci->CI_flags &= ~CI_INTERTHREAD_HOOK;
    00775         }
    00776
    00777         if ((INT)(SHORT)HIWORD(dwHookCurrent) == WH_CALLWNDPROC) {
    00778             nRet = CsSendMessage(
    00779                     ((LPCWPSTRUCT)lParam)->hwnd,
    00780                     ((LPCWPSTRUCT)lParam)->message,
    00781                     ((LPCWPSTRUCT)lParam)->wParam,
    00782                     ((LPCWPSTRUCT)lParam)->lParam,
    00783                     0, FNID_HKINLPCWPEXSTRUCT, bAnsi);
    00784         } else {
    00785             pci->dwHookData = ((LPCWPRETSTRUCT)lParam)->lResult;
    00786             nRet = CsSendMessage(
    00787                     ((LPCWPRETSTRUCT)lParam)->hwnd,
    00788                     ((LPCWPRETSTRUCT)lParam)->message,
    00789                     ((LPCWPRETSTRUCT)lParam)->wParam,
    00790                     ((LPCWPRETSTRUCT)lParam)->lParam,
    00791                     0, FNID_HKINLPCWPRETEXSTRUCT, bAnsi);
    00792         }
    00793
    00794         /*
    00795          * Restore previous hook state.
    00796          */
    00797         pci->CI_flags ^= ((pci->CI_flags ^ dwFlags) & CI_INTERTHREAD_HOOK);
    00798         pci->dwHookData = dwHookData;
    00799         break;
    00800
    00801     default:
    00802         nRet = NtUserCallNextHookEx(
    00803                 nCode,
    00804                 wParam,
    00805                 lParam,
    00806                 bAnsi);
    00807     }
    00808
    00809     return nRet;
    00810 }
    00811