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

cleanup.c File Reference

#include "precomp.h"

Go to the source code of this file.

Functions

VOID PseudoDestroyClassWindows (PWND pwndParent, PCLS pcls)
VOID _WOWModuleUnload (HANDLE hModule)
VOID _WOWCleanup (HANDLE hInstance, DWORD hTaskWow)


Function Documentation

VOID _WOWCleanup HANDLE  hInstance,
DWORD  hTaskWow
 

Definition at line 218 of file w32/ntuser/kernel/cleanup.c.

References tagSHAREDINFO::aheList, tagSERVERINFO::apfnClientA, _HANDLEENTRY::bFlags, tagHANDLETYPEINFO::bObjectCreateFlags, _HANDLEENTRY::bType, CSF_WOWDEFERDESTROY, DestroyClass(), DWORD, gahti, giheLast, gpsi, gSharedInfo, HANDLEF_DESTROY, HMDestroyUnlockedObject(), tagTDB::hTaskWow, tagWND::lpfnWndProc, NULL, OCF_PROCESSOWNED, tagPROCESSINFO::pclsPrivateList, tagPROCESSINFO::pclsPublicList, _PFNCLIENT::pfnDefWindowProc, _HANDLEENTRY::phead, _HANDLEENTRY::pOwner, tagTHREADINFO::ppi, PpiCurrent, PPROCOBJHEAD, tagTHREADINFO::ptdb, TestWF, TIF_16BIT, tagTHREADINFO::TIF_flags, TYPE_CALLPROC, TYPE_FREE, TYPE_WINDOW, VOID(), WFSERVERSIDEPROC, and WNDPROC_PWND.

Referenced by xxxDestroyThreadInfo().

00221 { 00222 PPROCESSINFO ppi = PpiCurrent(); 00223 PPCLS ppcls; 00224 PHE pheT, pheMax; 00225 int i; 00226 00227 if (hInstance != NULL) { 00228 00229 /* 00230 * Task cleanup 00231 */ 00232 00233 PWND pwnd; 00234 hTaskWow = (DWORD) LOWORD(hTaskWow); 00235 /* 00236 * Task exit called by wow. This loop will Pseudo-Destroy windows 00237 * created by this task. 00238 */ 00239 pheMax = &gSharedInfo.aheList[giheLast]; 00240 for (pheT = gSharedInfo.aheList; pheT <= pheMax; pheT++) { 00241 PTHREADINFO ptiTest = (PTHREADINFO)pheT->pOwner; 00242 if ((pheT->bType == TYPE_WINDOW) && 00243 (ptiTest->TIF_flags & TIF_16BIT) && 00244 (ptiTest->ptdb) && 00245 (ptiTest->ptdb->hTaskWow == hTaskWow) && 00246 (ptiTest->ppi == ppi)) { 00247 00248 pwnd = (PWND) pheT->phead; 00249 if (!TestWF(pwnd, WFSERVERSIDEPROC)) { 00250 pwnd->lpfnWndProc = (WNDPROC_PWND)gpsi->apfnClientA.pfnDefWindowProc; 00251 } 00252 } 00253 } 00254 return; 00255 } 00256 00257 /* 00258 * If we get here, we are in thread cleanup and all of the thread's windows 00259 * have been destroyed or disassociated with any classes. If a class 00260 * marked for destruction at this point still has windows, they must 00261 * belong to a dll. 00262 */ 00263 00264 /* 00265 * Destroy private classes marked for destruction 00266 */ 00267 ppcls = &(ppi->pclsPrivateList); 00268 for (i = 0; i < 2; ++i) { 00269 while (*ppcls != NULL) { 00270 if ((*ppcls)->hTaskWow == hTaskWow && 00271 ((*ppcls)->CSF_flags & CSF_WOWDEFERDESTROY)) { 00272 if ((*ppcls)->cWndReferenceCount == 0) { 00273 DestroyClass(ppcls); 00274 } else { 00275 RIPMSG0(RIP_ERROR, "Windows remain for a WOW class marked for destruction"); 00276 ppcls = &((*ppcls)->pclsNext); 00277 } 00278 } else 00279 ppcls = &((*ppcls)->pclsNext); 00280 } 00281 00282 /* 00283 * Destroy public classes marked for destruction 00284 */ 00285 ppcls = &(ppi->pclsPublicList); 00286 } 00287 00288 /* 00289 * Destroy menus, cursors, icons and accel tables identified by hTaskWow 00290 */ 00291 pheMax = &gSharedInfo.aheList[giheLast]; 00292 for (pheT = gSharedInfo.aheList; pheT <= pheMax; pheT++) { 00293 00294 /* 00295 * Check against free before we look at ppi... because pq is stored 00296 * in the object itself, which won't be there if TYPE_FREE. 00297 */ 00298 if (pheT->bType == TYPE_FREE) 00299 continue; 00300 00301 /* 00302 * Destroy those objects created by this task. 00303 */ 00304 if ( !(gahti[pheT->bType].bObjectCreateFlags & OCF_PROCESSOWNED) || 00305 (PPROCESSINFO)pheT->pOwner != ppi || 00306 (((PPROCOBJHEAD)pheT->phead)->hTaskWow != hTaskWow) || 00307 (pheT->bType == TYPE_CALLPROC) /* Do not destroy CALLPROCDATA objects. 00308 * These should only get nuked when the 00309 * process goes away or when the class 00310 * is nuked. 00311 */ 00312 ) { 00313 00314 continue; 00315 } 00316 00317 /* 00318 * Make sure this object isn't already marked to be destroyed - we'll 00319 * do no good if we try to destroy it now since it is locked. 00320 */ 00321 if (pheT->bFlags & HANDLEF_DESTROY) { 00322 continue; 00323 } 00324 00325 /* 00326 * Destroy this object. 00327 */ 00328 HMDestroyUnlockedObject(pheT); 00329 } 00330 }

VOID _WOWModuleUnload HANDLE  hModule  ) 
 

Definition at line 99 of file w32/ntuser/kernel/cleanup.c.

References tagSHAREDINFO::aheList, tagSERVERINFO::apfnClientA, tagSERVERINFO::apfnClientW, tagCLS::atomClassName, tagSERVERINFO::atomSysClass, _HANDLEENTRY::bType, tagCLS::CSF_flags, CSF_WOWCLASS, CSF_WOWDEFERDESTROY, DestroyClass(), giheLast, gpfnwp, gpsi, gSharedInfo, ICLS_BUTTON, ICLS_MAX, tagWND::lpfnWndProc, NULL, tagPROCESSINFO::pclsPrivateList, tagPROCESSINFO::pclsPublicList, _PFNCLIENT::pfnDefWindowProc, _HANDLEENTRY::phead, _HANDLEENTRY::pOwner, tagTHREADINFO::ppi, PpiCurrent, PseudoDestroyClassWindows(), PtiCurrent, PWCFromPCLS, TestWF, TIF_16BIT, tagTHREADINFO::TIF_flags, TYPE_WINDOW, VOID(), WFSERVERSIDEPROC, and WNDPROC_PWND.

00099 { 00100 PPROCESSINFO ppi = PpiCurrent(); 00101 PHE pheT, pheMax; 00102 PPCLS ppcls; 00103 int i; 00104 00105 UserAssert(gpfnwp[0]); 00106 00107 /* 00108 * PseudoDestroy windows with wndprocs from this hModule 00109 * If its a wow16 wndproc, check if the hMod16 is this module 00110 * and Nuke matches. 00111 */ 00112 pheMax = &gSharedInfo.aheList[giheLast]; 00113 for (pheT = gSharedInfo.aheList; pheT <= pheMax; pheT++) { 00114 PTHREADINFO ptiTest = (PTHREADINFO)pheT->pOwner; 00115 PWND pwnd; 00116 if ((pheT->bType == TYPE_WINDOW) && 00117 (ptiTest->TIF_flags & TIF_16BIT) && 00118 (ptiTest->ppi == ppi)) { 00119 00120 pwnd = (PWND) pheT->phead; 00121 if (!TestWF(pwnd, WFSERVERSIDEPROC) && 00122 IsWOWProc(pwnd->lpfnWndProc) && 00123 (pwnd->hMod16 == (WORD)(ULONG_PTR)hModule)) { 00124 pwnd->lpfnWndProc = (WNDPROC_PWND)gpsi->apfnClientA.pfnDefWindowProc; 00125 } 00126 } 00127 } 00128 00129 /* 00130 * Destroy private classes identified by hInstance that are not 00131 * referenced by any windows. Mark in-use classes for later 00132 * destruction. 00133 */ 00134 ppcls = &(ppi->pclsPrivateList); 00135 00136 for (i = 0; i < 2; ++i) { 00137 while (*ppcls != NULL) { 00138 00139 PWC pwc; 00140 PCLS pcls; 00141 00142 if (HIWORD((ULONG_PTR)(*ppcls)->hModule) == (WORD)(ULONG_PTR)hModule) { 00143 if ((*ppcls)->cWndReferenceCount == 0) { 00144 DestroyClass(ppcls); 00145 /* 00146 * DestroyClass does *ppcls = pcls->pclsNext; 00147 * so we just want continue here 00148 */ 00149 } else { 00150 00151 /* 00152 * Zap all the windows around that belong to this class. 00153 */ 00154 PseudoDestroyClassWindows(PtiCurrent()->rpdesk->pDeskInfo->spwnd, *ppcls); 00155 00156 /* 00157 * Win 3.1 does not distinguish between Dll's and Exe's 00158 */ 00159 (*ppcls)->CSF_flags |= CSF_WOWDEFERDESTROY; 00160 ppcls = &((*ppcls)->pclsNext); 00161 } 00162 continue; 00163 } 00164 00165 pcls = *ppcls; 00166 00167 if ((pcls->CSF_flags & CSF_WOWCLASS) && ((WORD)(ULONG_PTR)hModule == (pwc = PWCFromPCLS(pcls))->hMod16)) { 00168 00169 ATOM atom; 00170 int iSel; 00171 00172 /* 00173 * See if the window's class atom matches any of 00174 * the system ones. If so, jam in the original window proc. 00175 * Otherwise, use DefWindowProc 00176 */ 00177 atom = (*ppcls)->atomClassName; 00178 for (iSel = ICLS_BUTTON; iSel < ICLS_MAX; iSel++) { 00179 if ((gpfnwp[iSel]) && (atom == gpsi->atomSysClass[iSel])) { 00180 (*ppcls)->lpfnWndProc = (WNDPROC_PWND)gpfnwp[iSel]; 00181 break; 00182 } 00183 } 00184 if (iSel == ICLS_MAX) 00185 (*ppcls)->lpfnWndProc = (WNDPROC_PWND)gpsi->apfnClientW.pfnDefWindowProc; 00186 } 00187 00188 ppcls = &((*ppcls)->pclsNext); 00189 } 00190 00191 /* 00192 * Destroy public classes identified by hInstance that are not 00193 * referenced by any windows. Mark in-use classes for later 00194 * destruction. 00195 */ 00196 ppcls = &(ppi->pclsPublicList); 00197 } 00198 return; 00199 00200 }

VOID PseudoDestroyClassWindows PWND  pwndParent,
PCLS  pcls
 

Definition at line 42 of file w32/ntuser/kernel/cleanup.c.

References tagSERVERINFO::apfnClientA, GETPTI, gpsi, tagWND::lpfnWndProc, NULL, tagWND::pcls, _PFNCLIENT::pfnDefWindowProc, PtiCurrent, tagWND::spwndChild, tagWND::spwndNext, TestWF, VOID(), WFSERVERSIDEPROC, and WNDPROC_PWND.

Referenced by _WOWModuleUnload().

00043 { 00044 PWND pwnd; 00045 PTHREADINFO pti; 00046 00047 pti = PtiCurrent(); 00048 00049 /* 00050 * Recursively walk the window list and zombie any windows of this class 00051 */ 00052 for (pwnd = pwndParent->spwndChild; pwnd != NULL; pwnd = pwnd->spwndNext) { 00053 00054 /* 00055 * If this window belongs to this class then zombie it 00056 * if it was created by this message thread. 00057 */ 00058 if (pwnd->pcls == pcls && pti == GETPTI(pwnd)) { 00059 00060 /* 00061 * Zombie-ize the window 00062 * 00063 * Remove references to the client side window proc because that 00064 * WOW selector has been freed. 00065 */ 00066 00067 RIPMSG1(RIP_WARNING, 00068 "USER: Wow Window not destroyed: %lX", pwnd); 00069 00070 if (!TestWF(pwnd, WFSERVERSIDEPROC)) { 00071 pwnd->lpfnWndProc = (WNDPROC_PWND)gpsi->apfnClientA.pfnDefWindowProc; 00072 } 00073 } 00074 00075 /* 00076 * Recurse downward to look for any children that might be 00077 * of this class. 00078 */ 00079 if (pwnd->spwndChild != NULL) 00080 PseudoDestroyClassWindows(pwnd, pcls); 00081 } 00082 }


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