test: enumwin.c File Reference

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

# enumwin.c File Reference

`#include "precomp.h"`

Go to the source code of this file.

## Defines

#define | CHWND_BWLCREATE 32
#define | BWLGROW 8

## Functions

PBWL | InternalBuildHwndList (PBWL pbwl, PWND pwnd, UINT flags)
PBWL | InternalBuildHwndOwnerList (PBWL pbwl, PWND pwndStart, PWND pwndOwner)
BOOL | xxxInternalEnumWindow (PWND pwndNext, WNDENUMPROC_PWND lpfn, LPARAM lParam, UINT flags)
PBWL | BuildHwndList (PWND pwnd, UINT flags, PTHREADINFO pti)
BOOL | ExpandWindowList (PBWL *ppbwl)
void | FreeHwndList (PBWL pbwl)

## Variables

PBWL | pbwlCache

## Define Documentation

#define BWLGROW 8

| Definition at line 345 of file enumwin.c.

#define CHWND_BWLCREATE 32

| Definition at line 89 of file enumwin.c. Referenced by BuildHwndList().

## Function Documentation

PBWL BuildHwndList | ( | PWND | pwnd,
|  | UINT | flags,
|  | PTHREADINFO | pti
| ) |

Definition at line 91 of file enumwin.c.

References BWL, BWL_ENUMIMELAST, BWL_ENUMOWNERLIST, BWL_REMOVEIMECHILD, CheckCritIn, CHWND_BWLCREATE, gpbwlList, InternalBuildHwndList(), InternalBuildHwndOwnerList(), IS_IME_ENABLED, NULL, pbwlCache, tagBWL::pbwlNext, tagBWL::phwndMax, tagBWL::phwndNext, PtiCurrent, tagBWL::ptiOwner, and tagBWL::rghwnd.

Referenced by _FindWindowEx(), ArrangeWindows(), AssociateInputContextEx(), CascadeWindowsEnum(), DestroyInputContext(), InitSwitchWndInfo(), InternalEnumWindows(), NtUserBuildHwndList(), StartTaskModalDialog(), UnmaximizeChildWindows(), xxxArrangeIconicWindows(), xxxCheckImeShowStatus(), xxxClientShutdown(), xxxDefWindowProc(), xxxDesktopRecalc(), xxxDWPPrint(), xxxInternalDoSyncPaint(), xxxInternalEnumWindow(), xxxMetricsRecalc(), xxxSendBSMtoDesktop(), and xxxShowOwnedWindows().

    00095 {
    00096     PBWL pbwl;
    00097
    00098     CheckCritIn();
    00099
    00100     if ((pbwl = pbwlCache) != NULL) {
    00101
    00102         /*
    00103          * We're using the cache now; zero it out.
    00104          */
    00105 #if DBG
    00106         pbwlCachePrev = pbwlCache;
    00107 #endif
    00108         pbwlCache = NULL;
    00109
    00110 #if DBG
    00111         {
    00112             PBWL pbwlT;
    00113             /*
    00114              * pbwlCache shouldn't be in the global linked list.
    00115              */
    00116             for (pbwlT = gpbwlList; pbwlT != NULL; pbwlT = pbwlT->pbwlNext) {
    00117                 UserAssert(pbwlT != pbwl);
    00118             }
    00119         }
    00120 #endif
    00121     } else {
    00122
    00123         /*
    00124          * sizeof(BWL) includes the first element of array.
    00125          */
    00126         pbwl = (PBWL)UserAllocPool(sizeof(BWL) + sizeof(PWND) * CHWND_BWLCREATE,
    00127                 TAG_WINDOWLIST);
    00128         if (pbwl == NULL)
    00129             return NULL;
    00130
    00131         pbwl->phwndMax = &pbwl->rghwnd[CHWND_BWLCREATE - 1];
    00132     }
    00133     pbwl->phwndNext = pbwl->rghwnd;
    00134
    00135     /*
    00136      * We'll use ptiOwner as temporary storage for the thread we're
    00137      * scanning for. It will get reset to the proper thing at the bottom
    00138      * of this routine.
    00139      */
    00140     pbwl->ptiOwner = pti;
    00141
    00142 #ifdef OWNERLIST
    00143     if (flags & BWL_ENUMOWNERLIST) {
    00144         pbwl = InternalBuildHwndOwnerList(pbwl, pwnd, NULL);
    00145     } else {
    00146         pbwl = InternalBuildHwndList(pbwl, pwnd, flags);
    00147     }
    00148 #else
    00149     pbwl = InternalBuildHwndList(pbwl, pwnd, flags);
    00150 #endif
    00151
    00152     /*
    00153      * If phwndNext == phwndMax, it indicates that the pbwl has failed to expand.
    00154      * The list is no longer valid, so we should just bail.
    00155      */
    00156     if (pbwl->phwndNext >= pbwl->phwndMax) {
    00157         UserAssert(pbwl->phwndNext == pbwl->phwndMax);
    00158         /*
    00159          * Even if we had picked pbwl from the global single cache (pbwlCache),
    00160          * it should have already been unlinked from the global link list when it was put in the cache.
    00161          * So we should just free it without manupilating the link pointers.
    00162          * If we have allocated the pwbl for ourselves, we can simply free it.
    00163          * In both cases, we should just call UserFreePool().
    00164          * As the side effect, it may make some room by providing a free pool block.
    00165          */
    00166         UserFreePool(pbwl);
    00167         return NULL;
    00168     }
    00169
    00170     /*
    00171      * Stick in the terminator.
    00172      */
    00173     *pbwl->phwndNext = (HWND)1;
    00174
    00175 #ifdef FE_IME
    00176     if (flags & BWL_ENUMIMELAST) {
    00177         UserAssert(IS_IME_ENABLED());
    00178         /*
    00179          * For IME windows.
    00180          * Rebuild window list for EnumWindows API. Because ACCESS 2.0 assumes
    00181          * the first window that is called CallBack Functions in the task is
    00182          * Q-Card Wnd. We should change the order of IME windows
    00183          */
    00184         pbwl = InternalRebuildHwndListForIMEClass(pbwl,
    00185                     (flags & BWL_REMOVEIMECHILD) == BWL_REMOVEIMECHILD);
    00186     }
    00187 #endif
    00188
    00189     /*
    00190      * Finally link this guy into the list.
    00191      */
    00192     pbwl->ptiOwner = PtiCurrent();
    00193     pbwl->pbwlNext = gpbwlList;
    00194     gpbwlList = pbwl;
    00195
    00196
    00197     /*
    00198      * We should have given out the cache if it was available
    00199      */
    00200     UserAssert(pbwlCache == NULL);
    00201
    00202     return pbwl;
    00203 }

BOOL ExpandWindowList | ( | PBWL * | ppbwl | ) |

Definition at line 213 of file enumwin.c.

References BOOL, BWL_CHWNDMORE, BYTE, FALSE, NULL, tagBWL::phwndNext, PWND, and TRUE.

Referenced by InternalBuildHwndList().

    00215 {
    00216     PBWL pbwl;
    00217     PBWL pbwlT;
    00218     HWND *phwnd;
    00219
    00220     pbwl = *ppbwl;
    00221     phwnd = pbwl->phwndNext;
    00222
    00223     /*
    00224      * Map phwnd to an offset.
    00225      */
    00226     phwnd = (HWND *)((BYTE *)phwnd - (BYTE *)pbwl);
    00227
    00228     /*
    00229      * Increase size of BWL by 8 slots.  (8 + 1) is
    00230      * added since phwnd is "sizeof(HWND)" less
    00231      * than actual size of handle.
    00232      */
    00233     pbwlT = (PBWL)UserReAllocPool((HANDLE)pbwl,
    00234             PtrToUlong(phwnd) + sizeof(PWND),
    00235             PtrToUlong(phwnd) + (BWL_CHWNDMORE + 1) * sizeof(PWND),
    00236             TAG_WINDOWLIST);
    00237
    00238     /*
    00239      * Did alloc succeed?
    00240      */
    00241     if (pbwlT != NULL)
    00242         pbwl = pbwlT;                 /* Yes, use new block. */
    00243
    00244     /*
    00245      * Map phwnd back into a pointer.
    00246      */
    00247     phwnd = (HWND *)((ULONG_PTR)pbwl + (ULONG_PTR)phwnd);
    00248
    00249     /*
    00250      * Did ReAlloc() fail?
    00251      */
    00252     if (pbwlT == NULL) {
    00253         RIPMSG0(RIP_WARNING, "ExpandWindowList: out of memory.");
    00254         return FALSE;
    00255     }
    00256
    00257     /*
    00258      * Reset phwndMax.
    00259      */
    00260     pbwl->phwndNext = phwnd;
    00261     pbwl->phwndMax = phwnd + BWL_CHWNDMORE;
    00262
    00263     *ppbwl = pbwl;
    00264
    00265     return TRUE;
    00266 }

void FreeHwndList | ( | PBWL | pbwl | ) |

Definition at line 417 of file enumwin.c.

References CheckCritIn, FALSE, gpbwlList, NULL, pbwlCache, tagBWL::pbwlNext, tagBWL::phwndMax, and tagBWL::rghwnd.

Referenced by _FindWindowEx(), AssociateInputContextEx(), DestroyInputContext(), InitSwitchWndInfo(), NtUserBuildHwndList(), SwitchWndCleanup(), xxxArrangeIconicWindows(), xxxCheckImeShowStatus(), xxxClientShutdown(), xxxDefWindowProc(), xxxDesktopRecalc(), xxxDestroyThreadInfo(), xxxDWPPrint(), xxxInternalDoSyncPaint(), xxxInternalEnumWindow(), xxxMetricsRecalc(), xxxSendBSMtoDesktop(), and xxxShowOwnedWindows().

    00419 {
    00420     PBWL *ppbwl;
    00421     PBWL pbwlT;
    00422
    00423     CheckCritIn();
    00424
    00425     /*
    00426      * We should never have an active bwl that is the free cached bwl
    00427      */
    00428     UserAssert(pbwl != pbwlCache);
    00429
    00430     /*
    00431      * Unlink this bwl from the list.
    00432      */
    00433     for (ppbwl = &gpbwlList; *ppbwl != NULL; ppbwl = &(*ppbwl)->pbwlNext) {
    00434         if (*ppbwl == pbwl) {
    00435             *ppbwl = pbwl->pbwlNext;
    00436
    00437             /*
    00438              * If the cache is empty or this pbwl is larger than the
    00439              * cached one, save the pbwl there.
    00440              */
    00441             if (pbwlCache == NULL) {
    00442                 pbwlCache = pbwl;
    00443             } else if ((pbwl->phwndMax - pbwl->rghwnd) >
    00444                        (pbwlCache->phwndMax - pbwlCache->rghwnd)) {
    00445                 pbwlT = pbwlCache;
    00446                 pbwlCache = pbwl;
    00447                 UserFreePool((HANDLE)pbwlT);
    00448             } else {
    00449                 UserFreePool((HANDLE)pbwl);
    00450             }
    00451             return;
    00452         }
    00453     }
    00454
    00455     /*
    00456      * Assert if we couldn't find the pbwl in the list...
    00457      */
    00458     UserAssert(FALSE);
    00459 }

PBWL InternalBuildHwndList | ( | PBWL | pbwl,
|  | PWND | pwnd,
|  | UINT | flags
| ) |

Definition at line 347 of file enumwin.c.

References BWL_ENUMCHILDREN, BWL_ENUMLIST, ExpandWindowList(), GETPTI, HWq, n, NULL, tagBWL::phwndMax, tagBWL::phwndNext, tagBWL::ptiOwner, tagWND::spwndChild, and tagWND::spwndNext.

Referenced by BuildHwndList().

    00351 {
    00352     /*
    00353      * NOTE: pbwl->phwndNext is used as a place to keep
    00354      *       the phwnd across calls to InternalBuildHwndList().
    00355      *       This is OK since we don't link pbwl into the list
    00356      *       of pbwl's until after we've finished enumerating windows.
    00357      */
    00358
    00359     while (pwnd != NULL) {
    00360         /*
    00361          * Make sure it matches the thread id, if there is one.
    00362          */
    00363         if (pbwl->ptiOwner == NULL || pbwl->ptiOwner == GETPTI(pwnd)) {
    00364             UserAssert(pbwl->phwndNext < pbwl->phwndMax);
    00365             *pbwl->phwndNext = HWq(pwnd);
    00366             pbwl->phwndNext++;
    00367             if (pbwl->phwndNext == pbwl->phwndMax) {
    00368 #if EMULATE_EXPAND_FAILURE
    00369                 static int n = 0;
    00370                 if (++n % 32 == 0) {
    00371                     RIPMSG0(RIP_WARNING, "InternalBuildHwndList: emulating ExpandWindowList failure.");
    00372                     break;
    00373                 }
    00374 #endif
    00375                 if (!ExpandWindowList(&pbwl))
    00376                     break;
    00377             }
    00378         }
    00379
    00380         /*
    00381          * Should we step through the Child windows?
    00382          */
    00383         if ((flags & BWL_ENUMCHILDREN) && pwnd->spwndChild != NULL) {
    00384             pbwl = InternalBuildHwndList(pbwl, pwnd->spwndChild, BWL_ENUMLIST | BWL_ENUMCHILDREN);
    00385             /*
    00386              * If ExpandWindowList() failed in the recursive call,
    00387              * we should just bail.
    00388              */
    00389             if (pbwl->phwndNext >= pbwl->phwndMax) {
    00390                 UserAssert(pbwl->phwndNext == pbwl->phwndMax);
    00391                 RIPMSG1(RIP_WARNING, "InternalBuildHwndList: failed to expand BWL in enumerating children. pbwl=%#p", pbwl);
    00392                 break;
    00393             }
    00394             UserAssert(pbwl->phwndNext < pbwl->phwndMax);
    00395         }
    00396
    00397         /*
    00398          * Are we enumerating only one window?
    00399          */
    00400         if (!(flags & BWL_ENUMLIST))
    00401             break;
    00402
    00403         pwnd = pwnd->spwndNext;
    00404     }
    00405
    00406     return pbwl;
    00407 }

PBWL InternalBuildHwndOwnerList | ( | PBWL | pbwl,
|  | PWND | pwndStart,
|  | PWND | pwndOwner
| ) |

| Referenced by BuildHwndList().

BOOL xxxInternalEnumWindow | ( | PWND | pwndNext,
|  | WNDENUMPROC_PWND | lpfn,
|  | LPARAM | lParam,
|  | UINT | flags
| ) |

Definition at line 40 of file enumwin.c.

References BOOL, BuildHwndList(), CheckLock, FALSE, FreeHwndList(), NULL, RevalidateHwnd, tagBWL::rghwnd, ThreadLockAlways, ThreadUnlock, TRUE, and WNDENUMPROC_PWND.

Referenced by CancelInputState(), xxxActivateThisWindow(), xxxDeactivate(), xxxHelpLoop(), and xxxSetClassIcon().

    00045 {
    00046     HWND *phwnd;
    00047     PWND pwnd;
    00048     PBWL pbwl;
    00049     BOOL fSuccess;
    00050     TL tlpwnd;
    00051
    00052     CheckLock(pwndNext);
    00053
    00054     if ((pbwl = BuildHwndList(pwndNext, flags, NULL)) == NULL)
    00055         return FALSE;
    00056
    00057     fSuccess = TRUE;
    00058     for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) {
    00059
    00060         /*
    00061          * Lock the window before we pass it off to the app.
    00062          */
    00063         if ((pwnd = RevalidateHwnd(*phwnd)) != NULL) {
    00064
    00065             /*
    00066              * Call the application.
    00067              */
    00068             ThreadLockAlways(pwnd, &tlpwnd);
    00069             fSuccess = (*lpfn)(pwnd, lParam);
    00070             ThreadUnlock(&tlpwnd);
    00071             if (!fSuccess)
    00072                 break;
    00073         }
    00074     }
    00075
    00076     FreeHwndList(pbwl);
    00077
    00078     return fSuccess;
    00079 }

## Variable Documentation

PBWL pbwlCache

| Definition at line 17 of file enumwin.c. Referenced by BuildHwndList(), FreeHwndList(), and Win32kNtUserCleanup().