test: kernel/exitwin.c File Reference

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

# exitwin.c File Reference

`#include "precomp.h"`

Go to the source code of this file.

## Defines

#define | OPTIONMASK (EWX_SHUTDOWN | EWX_REBOOT | EWX_FORCE)

## Functions

BOOL | PrepareForLogoff (UINT uFlags)
BOOL | NotifyLogon (PWINDOWSTATION pwinsta, PLUID pluidCaller, DWORD dwFlags, NTSTATUS StatusCode)
NTSTATUS | InitiateShutdown (PETHREAD Thread, PULONG lpdwFlags)
NTSTATUS | EndShutdown (PETHREAD Thread, NTSTATUS StatusShutdown)
LONG | xxxClientShutdown2 (PBWL pbwl, UINT msg, WPARAM wParam)
LONG | xxxClientShutdown (PWND pwnd, WPARAM wParam)
BOOL | xxxRegisterUserHungAppHandlers (PFNW32ET pfnW32EndTask, HANDLE hEventWowExec)

## Variables

PWINDOWSTATION | gpwinstaLogoff
DWORD | gdwLocks
DWORD | gdwShutdownFlags
HANDLE | gpidEndSession
PSECURITY_DESCRIPTOR | gpsdInitWinSta

## Define Documentation

#define OPTIONMASK (EWX_SHUTDOWN | EWX_REBOOT | EWX_FORCE)

| Definition at line 16 of file kernel/exitwin.c. Referenced by InitiateShutdown().

## Function Documentation

NTSTATUS EndShutdown | ( | PETHREAD | Thread,
|  | NTSTATUS | StatusShutdown
| ) |

Definition at line 324 of file kernel/exitwin.c.

References _PostThreadMessage(), CLEAR_PUDF, tagWINDOWSTATION::dwWSF_Flags, EnterCrit, FALSE, ForceEmptyClipboard(), gdwLocks, gdwShutdownFlags, gdwThreadEndSession, GetProcessLuid(), gpidEndSession, gptiShutdownNotify, gpwinstaLogoff, LeaveCrit, tagWINDOWSTATION::luidUser, NotifyLogon(), NT_SUCCESS, NTSTATUS(), NULL, tagWINDOWSTATION::pGlobalAtomTable, tagDESKTOP::pheapDesktop, PUDF_FONTSARELOADED, tagWINDOWSTATION::rpdeskList, tagDESKTOP::rpdeskNext, RtlEmptyAtomTable(), RtlEqualLuid(), RtlZeroHeap(), TEST_PUDF, WSF_OPENLOCK, and WSF_SHUTDOWN.

Referenced by xxxSetInformationThread().

    00327 {
    00328     PWINDOWSTATION pwinsta = gpwinstaLogoff;
    00329     PDESKTOP pdesk;
    00330     LUID luidCaller;
    00331     UserAssert(gpwinstaLogoff);
    00332
    00333     gpwinstaLogoff = NULL;
    00334     gpidEndSession = NULL;
    00335     gdwThreadEndSession = 0;
    00336     pwinsta->dwWSF_Flags &= ~WSF_SHUTDOWN;
    00337
    00338     if (!NT_SUCCESS(GetProcessLuid(Thread, &luidCaller))) {
    00339         luidCaller = RtlConvertUlongToLuid(0);     // null luid
    00340     }
    00341
    00342     if (!NT_SUCCESS(StatusShutdown)) {
    00343
    00344         /*
    00345          * We need to notify the process that called ExitWindows that
    00346          * the logoff was aborted.
    00347          */
    00348         if (gptiShutdownNotify) {
    00349             _PostThreadMessage(gptiShutdownNotify, WM_ENDSESSION, FALSE, 0);
    00350             gptiShutdownNotify = NULL;
    00351         }
    00352
    00353         /*
    00354          * Reset the windowstation lock flags so apps can start
    00355          * again.
    00356          */
    00357         pwinsta->dwWSF_Flags =
    00358                 (pwinsta->dwWSF_Flags & ~WSF_OPENLOCK) |
    00359                 gdwLocks;
    00360
    00361         /*
    00362          * Bug 294204 - joejo
    00363          * Tell winlogon that we we cancelled shutdown/logoff.
    00364          */
    00365         NotifyLogon(pwinsta, &luidCaller, gdwShutdownFlags | EWX_CANCELED, StatusShutdown);
    00366
    00367         return STATUS_SUCCESS;
    00368     }
    00369
    00370     gptiShutdownNotify = NULL;
    00371
    00372     /*
    00373      * If logoff is occuring for the user set by winlogon, perform
    00374      * the normal logoff cleanup.  Otherwise, clear the open lock
    00375      * and continue.
    00376      */
    00377     if (((pwinsta->luidUser.LowPart != 0) || (pwinsta->luidUser.HighPart != 0)) &&
    00378             RtlEqualLuid(&pwinsta->luidUser, &luidCaller)) {
    00379
    00380         /*
    00381          * Zero out the free blocks in all desktop heaps.
    00382          */
    00383         for (pdesk = pwinsta->rpdeskList; pdesk != NULL; pdesk = pdesk->rpdeskNext) {
    00384             RtlZeroHeap(Win32HeapGetHandle(pdesk->pheapDesktop), 0);
    00385         }
    00386
    00387         /*
    00388          * Logoff/shutdown was successful. In case this is a logoff, remove
    00389          * everything from the clipboard so the next logged on user can't get
    00390          * at this stuff.
    00391          */
    00392         ForceEmptyClipboard(pwinsta);
    00393
    00394         /*
    00395          * Destroy all non-pinned atoms in the global atom table.  User can't
    00396          * create pinned atoms.  Currently only the OLE atoms are pinned.
    00397          */
    00398         RtlEmptyAtomTable(pwinsta->pGlobalAtomTable, FALSE);
    00399
    00400         // this code path is hit only on logoff and also on shutdown
    00401         // We do not want to unload fonts twice when we attempt shutdown
    00402         // so we mark that the fonts have been unloaded at a logoff time
    00403
    00404         if (TEST_PUDF(PUDF_FONTSARELOADED)) {
    00405             LeaveCrit();
    00406             GreRemoveAllButPermanentFonts();
    00407             EnterCrit();
    00408             CLEAR_PUDF(PUDF_FONTSARELOADED);
    00409         }
    00410     } else {
    00411         pwinsta->dwWSF_Flags &= ~WSF_OPENLOCK;
    00412     }
    00413
    00414     /*
    00415      * Tell winlogon that we successfully shutdown/logged off.
    00416      */
    00417     NotifyLogon(pwinsta, &luidCaller, gdwShutdownFlags, STATUS_SUCCESS);
    00418
    00419     return STATUS_SUCCESS;
    00420 }

NTSTATUS InitiateShutdown | ( | PETHREAD | Thread,
|  | PULONG | lpdwFlags
| ) |

Definition at line 119 of file kernel/exitwin.c.

References tagPROCESSINFO::amwinsta, _ETHREAD::Cid, tagTHREADINFO::cWindows, dwFlags, DWORD, tagWINDOWSTATION::dwWSF_Flags, gdwLocks, gdwShutdownFlags, gdwThreadEndSession, GetProcessLuid(), gpidEndSession, gpidLogon, gptiShutdownNotify, gpwinstaLogoff, tagPROCESSINFO::hwinsta, IsPrivileged(), tagWINDOWSTATION::luidEndSession, luidSystem, NotifyLogon(), NT_SUCCESS, NTSTATUS(), NULL, OPTIONMASK, PpiFromProcess, PsGetCurrentThread, PtiFromThread, tagPROCESSINFO::rpwinsta, RtlAreAllAccessesGranted(), RtlEqualLuid(), Status, THREAD_TO_PROCESS, TIF_16BIT, tagTHREADINFO::TIF_flags, WSF_NOIO, WSF_OPENLOCK, WSF_REALSHUTDOWN, WSF_SHUTDOWN, and WSF_SWITCHLOCK.

Referenced by xxxSetInformationThread().

    00122 {
    00123     static PRIVILEGE_SET psShutdown = {
    00124         1, PRIVILEGE_SET_ALL_NECESSARY, { SE_SHUTDOWN_PRIVILEGE, 0 }
    00125     };
    00126     PEPROCESS Process;
    00127     LUID luidCaller;
    00128     PPROCESSINFO ppi;
    00129     PWINDOWSTATION pwinsta;
    00130     HWINSTA hwinsta;
    00131     PTHREADINFO ptiClient;
    00132     NTSTATUS Status;
    00133     DWORD dwFlags;
    00134
    00135     /*
    00136      * Find out the callers sid. Only want to shutdown processes in the
    00137      * callers sid.
    00138      */
    00139     Process = THREAD_TO_PROCESS(Thread);
    00140     ptiClient = PtiFromThread(Thread);
    00141     Status = GetProcessLuid(Thread, &luidCaller);
    00142
    00143     if (!NT_SUCCESS(Status)) {
    00144         return Status;
    00145     }
    00146
    00147     /*
    00148      * Set the system flag if the caller is a system process.
    00149      * Winlogon uses this to determine in which context to perform
    00150      * a shutdown operation.
    00151      */
    00152     dwFlags = *lpdwFlags;
    00153     if (RtlEqualLuid(&luidCaller, &luidSystem)) {
    00154         dwFlags |= EWX_SYSTEM_CALLER;
    00155     } else {
    00156         dwFlags &= ~EWX_SYSTEM_CALLER;
    00157     }
    00158
    00159     /*
    00160      * Find a windowstation.  If the process does not have one
    00161      * assigned, use the standard one.
    00162      */
    00163     ppi = PpiFromProcess(Process);
    00164     if (ppi == NULL) {
    00165         /*
    00166          * We ran into a case where the thread was terminated and had already
    00167          * been cleaned up by USER.  Thus, the ppi and ptiClient was NULL.
    00168          */
    00169         return STATUS_INVALID_HANDLE;
    00170     }
    00171     pwinsta = ppi->rpwinsta;
    00172     hwinsta = ppi->hwinsta;
    00173     /*
    00174      * If we're not being called by Winlogon, validate the call and
    00175      * notify the logon process to do the actual shutdown.
    00176      */
    00177     if (Thread->Cid.UniqueProcess != gpidLogon) {
    00178         dwFlags &= ~EWX_WINLOGON_CALLER;
    00179         *lpdwFlags = dwFlags;
    00180
    00181         if (pwinsta == NULL) {
    00182 #ifndef LATER
    00183             return STATUS_INVALID_HANDLE;
    00184 #else
    00185             hwinsta = ppi->pOpenObjectTable[HI_WINDOWSTATION].h;
    00186             if (hwinsta == NULL) {
    00187                 return STATUS_INVALID_HANDLE;
    00188             }
    00189             pwinsta = (PWINDOWSTATION)ppi->pOpenObjectTable[HI_WINDOWSTATION].phead;
    00190 #endif
    00191         }
    00192
    00193         /*
    00194          * Check security first - does this thread have access?
    00195          */
    00196         if (!RtlAreAllAccessesGranted(ppi->amwinsta, WINSTA_EXITWINDOWS)) {
    00197             return STATUS_ACCESS_DENIED;
    00198         }
    00199
    00200         /*
    00201          * If the client requested shutdown, reboot, or poweroff they must have
    00202          * the shutdown privilege.
    00203          */
    00204         if (dwFlags & EWX_SHUTDOWN) {
    00205             if (!IsPrivileged(&psShutdown) ) {
    00206                 return STATUS_PRIVILEGE_NOT_HELD;
    00207             }
    00208         } else {
    00209
    00210             /*
    00211              * If this is a non-IO windowstation and we are not shutting down,
    00212              * fail the call.
    00213              */
    00214             if (pwinsta->dwWSF_Flags & WSF_NOIO) {
    00215                 return STATUS_INVALID_DEVICE_REQUEST;
    00216             }
    00217         }
    00218     }
    00219
    00220     /*
    00221      * Is there a shutdown already in progress?
    00222      */
    00223     if (gdwThreadEndSession != 0) {
    00224         DWORD dwNew;
    00225
    00226         /*
    00227          * If the current shutdown in another sid and is not being done by
    00228          * winlogon, override it.
    00229          */
    00230         if (!RtlEqualLuid(&luidCaller, &gpwinstaLogoff->luidEndSession) &&
    00231                 (gpidEndSession != gpidLogon)) {
    00232             return STATUS_RETRY;
    00233         }
    00234
    00235         /*
    00236          * Calculate new flags
    00237          */
    00238         dwNew = dwFlags & OPTIONMASK & (~gdwShutdownFlags);
    00239
    00240         /*
    00241          * Should we override the other shutdown?  Make sure
    00242          * winlogon does not recurse.
    00243          */
    00244         if (dwNew && HandleToUlong(PsGetCurrentThread()->Cid.UniqueThread) !=
    00245                 gdwThreadEndSession) {
    00246             /*
    00247              * Only one windowstation can be logged off at a time.
    00248              */
    00249             if (!(dwFlags & EWX_SHUTDOWN) &&
    00250                     pwinsta != gpwinstaLogoff) {
    00251                 return STATUS_DEVICE_BUSY;
    00252             }
    00253
    00254             /*
    00255              * Set the new flags
    00256              */
    00257             gdwShutdownFlags = dwFlags;
    00258
    00259             if (dwNew & EWX_FORCE) {
    00260                 return STATUS_RETRY;
    00261             } else {
    00262                 return STATUS_PENDING;
    00263             }
    00264         } else {
    00265             /*
    00266              * Don't override
    00267              */
    00268             return STATUS_PENDING;
    00269         }
    00270     }
    00271
    00272     /*
    00273      * If the caller is not winlogon, signal winlogon to start
    00274      * the real shutdown.
    00275      */
    00276     if (Thread->Cid.UniqueProcess != gpidLogon) {
    00277         if (dwFlags & EWX_NOTIFY) {
    00278             if (ptiClient && ptiClient->TIF_flags & TIF_16BIT)
    00279                 gptiShutdownNotify = ptiClient;
    00280             dwFlags &= ~EWX_NOTIFY;
    00281             *lpdwFlags = dwFlags;
    00282         }
    00283
    00284         if (NotifyLogon(pwinsta, &luidCaller, dwFlags, STATUS_SUCCESS))
    00285             return STATUS_PENDING;
    00286         else if (ptiClient && ptiClient->cWindows)
    00287             return STATUS_CANT_WAIT;
    00288     }
    00289
    00290     /*
    00291      * Mark this thread as the one that is currently processing
    00292      * exit windows, and set the global saying someone is exiting
    00293      */
    00294     dwFlags |= EWX_WINLOGON_CALLER;
    00295     *lpdwFlags = dwFlags;
    00296     gdwShutdownFlags = dwFlags;
    00297
    00298     gdwThreadEndSession = HandleToUlong(PsGetCurrentThread()->Cid.UniqueThread);
    00299     gpidEndSession = PsGetCurrentThread()->Cid.UniqueProcess;
    00300     gpwinstaLogoff = pwinsta;
    00301     pwinsta->luidEndSession = luidCaller;
    00302
    00303     /*
    00304      * Lock the windowstation to prevent apps from starting
    00305      * while we're doing shutdown processing.
    00306      */
    00307     gdwLocks = pwinsta->dwWSF_Flags & (WSF_SWITCHLOCK | WSF_OPENLOCK);
    00308     pwinsta->dwWSF_Flags |= (WSF_OPENLOCK | WSF_SHUTDOWN);
    00309
    00310     /*
    00311      * Set the flag WSF_REALSHUTDOWN if we are not doing just a
    00312      * logoff
    00313      */
    00314     if (dwFlags &
    00315         (EWX_WINLOGON_OLD_SHUTDOWN | EWX_WINLOGON_OLD_REBOOT |
    00316          EWX_SHUTDOWN | EWX_REBOOT)) {
    00317
    00318         pwinsta->dwWSF_Flags |= WSF_REALSHUTDOWN;
    00319     }
    00320
    00321     return STATUS_SUCCESS;
    00322 }

BOOL NotifyLogon | ( | PWINDOWSTATION | pwinsta,
|  | PLUID | pluidCaller,
|  | DWORD | dwFlags,
|  | NTSTATUS | StatusCode
| ) |

Definition at line 77 of file kernel/exitwin.c.

References _PostMessage(), BOOL, dwFlags, DWORD, FALSE, gspwndLogonNotify, luidSystem, tagWINDOWSTATION::luidUser, NULL, RtlEqualLuid(), and TRUE.

Referenced by EndShutdown(), and InitiateShutdown().

    00082 {
    00083     BOOL fNotified = FALSE;
    00084     DWORD dwllParam;
    00085     DWORD dwStatus;
    00086
    00087     if (!(dwFlags & EWX_NONOTIFY)) {
    00088
    00089         if (dwFlags & EWX_CANCELED) {
    00090             dwllParam = LOGON_LOGOFFCANCELED;
    00091             dwStatus = StatusCode;
    00092         } else {
    00093             dwllParam = LOGON_LOGOFF;
    00094             dwStatus = dwFlags;
    00095         }
    00096
    00097         if (dwFlags & EWX_SHUTDOWN) {
    00098             /*
    00099              * Post the message to the global logon notify window
    00100              */
    00101             if (gspwndLogonNotify != NULL) {
    00102                 _PostMessage(gspwndLogonNotify, WM_LOGONNOTIFY,
    00103                              dwllParam, (LONG)dwStatus);
    00104                 fNotified = TRUE;
    00105             }
    00106         } else {
    00107             if (gspwndLogonNotify != NULL &&
    00108                     (RtlEqualLuid(&pwinsta->luidUser, pluidCaller) ||
    00109                      RtlEqualLuid(&luidSystem, pluidCaller))) {
    00110                 _PostMessage(gspwndLogonNotify, WM_LOGONNOTIFY, dwllParam,
    00111                         (LONG)dwStatus);
    00112                 fNotified = TRUE;
    00113             }
    00114         }
    00115     }
    00116     return fNotified;
    00117 }

BOOL PrepareForLogoff | ( | UINT | uFlags | ) |

Definition at line 33 of file kernel/exitwin.c.

References BOOL, CheckCritIn, CreateProfileUserName(), FALSE, FreeProfileUserName(), gpidLogon, NULL, tagTHREADINFO::ppi, PtiCurrent, PW32JOB, tagPROCESSINFO::pW32Job, RegisterPerUserKeyboardIndicators(), tagW32JOB::restrictions, tagTHREADINFO::TIF_flags, TIF_RESTRICTED, and TRUE.

    00035 {
    00036     PTHREADINFO ptiCurrent = PtiCurrent();
    00037
    00038     CheckCritIn();
    00039
    00040     if (ptiCurrent->TIF_flags & TIF_RESTRICTED) {
    00041         PW32JOB pW32Job;
    00042
    00043         pW32Job = ptiCurrent->ppi->pW32Job;
    00044
    00045         UserAssert(pW32Job != NULL);
    00046
    00047         if (pW32Job->restrictions & JOB_OBJECT_UILIMIT_EXITWINDOWS) {
    00048             // Not permitted to ExitWindows.
    00049             return FALSE;
    00050         }
    00051     }
    00052
    00053     /*
    00054      * There are no restrictions, or the restriction do not deny shutdown:
    00055      * The caller is about to ExitWindowsEx via CSR, so save the volatile
    00056      * elements of the User preferences in their profile
    00057      */
    00058     if (ptiCurrent->pEThread->Cid.UniqueProcess == gpidLogon) {
    00059         /*
    00060          * Save the current user's NumLock state
    00061          */
    00062         TL tlName;
    00063         PUNICODE_STRING pProfileUserName = CreateProfileUserName(&tlName);
    00064         RegisterPerUserKeyboardIndicators(pProfileUserName);
    00065         FreeProfileUserName(pProfileUserName, &tlName);
    00066     }
    00067
    00068     return TRUE;
    00069     UNREFERENCED_PARAMETER(uFlags);
    00070 }

LONG xxxClientShutdown | ( | PWND | pwnd,
|  | WPARAM | wParam
| ) |

Definition at line 521 of file kernel/exitwin.c.

References BuildHwndList(), BWL_ENUMLIST, FreeHwndList(), GETPTI, NULL, tagDESKTOP::pDeskInfo, tagTHREADINFO::rpdesk, tagDESKTOPINFO::spwnd, tagWND::spwndChild, WMCS_QUERYEND, WMCSR_ALLOWSHUTDOWN, WMCSR_DONE, and xxxClientShutdown2().

Referenced by xxxDefWindowProc().

    00524 {
    00525     PBWL pbwl;
    00526     PTHREADINFO ptiT;
    00527     LONG lRet;
    00528
    00529     /*
    00530      * Build a list of windows first.
    00531      */
    00532     ptiT = GETPTI(pwnd);
    00533
    00534     if ((pbwl = BuildHwndList(ptiT->rpdesk->pDeskInfo->spwnd->spwndChild,
    00535             BWL_ENUMLIST, ptiT)) == NULL) {
    00536         /*
    00537          * Can't allocate memory to notify this thread's windows of shutdown.
    00538          * Can't do more than kill the app
    00539          */
    00540         return WMCSR_ALLOWSHUTDOWN;
    00541     }
    00542
    00543     if (wParam & WMCS_QUERYEND) {
    00544         lRet = xxxClientShutdown2(pbwl, WM_QUERYENDSESSION, wParam);
    00545     } else {
    00546         xxxClientShutdown2(pbwl, WM_ENDSESSION, wParam);
    00547         lRet = WMCSR_DONE;
    00548     }
    00549
    00550     FreeHwndList(pbwl);
    00551     return lRet;
    00552 }

LONG xxxClientShutdown2 | ( | PBWL | pbwl,
|  | UINT | msg,
|  | WPARAM | wParam
| ) |

Definition at line 428 of file kernel/exitwin.c.

References BOOL, DestroyWindowsTimers(), FALSE, gptiShutdownNotify, msg, NULL, PtiCurrent, RevalidateHwnd, tagBWL::rghwnd, ThreadLockAlways, ThreadUnlock, TRUE, WMCS_CONTEXTLOGOFF, WMCS_EXIT, WMCSR_ALLOWSHUTDOWN, WMCSR_CANCEL, and xxxSendMessage().

Referenced by xxxClientShutdown().

    00432 {
    00433     HWND *phwnd;
    00434     PWND pwnd;
    00435     TL tlpwnd;
    00436     BOOL fEnd;
    00437     PTHREADINFO ptiCurrent = PtiCurrent();
    00438     BOOL fDestroyTimers;
    00439     LPARAM lParam;
    00440
    00441     /*
    00442      * Make sure we don't send this window any more WM_TIMER
    00443      * messages if the session is ending. This was causing
    00444      * AfterDark to fault when it freed some memory on the
    00445      * WM_ENDSESSION and then tried to reference it on the
    00446      * WM_TIMER.
    00447      * LATER GerardoB: Do we still need to do this??
    00448      * Do this horrible thing only if the process is in the
    00449      * context being logged off.
    00450      * Perhaps someday we should post a WM_CLOSE so the app
    00451      * gets a better chance to clean up (if this process is in
    00452      * the context being logged off, winsrv is going to call
    00453      * TerminateProcess soon after this).
    00454      */
    00455      fDestroyTimers = (wParam & WMCS_EXIT) && (wParam & WMCS_CONTEXTLOGOFF);
    00456
    00457      /*
    00458       * fLogOff and fEndSession parameters (WM_ENDSESSION only)
    00459       */
    00460      lParam = wParam & ENDSESSION_LOGOFF;
    00461      wParam &= WMCS_EXIT;
    00462
    00463     /*
    00464      * Now enumerate these windows and send the WM_QUERYENDSESSION or
    00465      * WM_ENDSESSION messages.
    00466      */
    00467     for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) {
    00468         if ((pwnd = RevalidateHwnd(*phwnd)) == NULL)
    00469             continue;
    00470
    00471         ThreadLockAlways(pwnd, &tlpwnd);
    00472
    00473         /*
    00474          * Send the message.
    00475          */
    00476         switch (msg) {
    00477         case WM_QUERYENDSESSION:
    00478
    00479             /*
    00480              * Windows does not send the WM_QUERYENDSESSION to the app
    00481              * that called ExitWindows
    00482              */
    00483             if (ptiCurrent == gptiShutdownNotify) {
    00484                 fEnd = TRUE;
    00485             } else {
    00486                 fEnd = (xxxSendMessage(pwnd, WM_QUERYENDSESSION, FALSE, lParam) != 0);
    00487                 if (!fEnd) {
    00488                     RIPMSG2(RIP_WARNING, "xxxClientShutdown2: pwnd:%p canceled shutdown. lParam:%p",
    00489                             pwnd, lParam);
    00490                 }
    00491             }
    00492             break;
    00493
    00494         case WM_ENDSESSION:
    00495             xxxSendMessage(pwnd, WM_ENDSESSION, wParam, lParam);
    00496             fEnd = TRUE;
    00497
    00498             if (fDestroyTimers) {
    00499                 DestroyWindowsTimers(pwnd);
    00500             }
    00501
    00502             break;
    00503         }
    00504
    00505         ThreadUnlock(&tlpwnd);
    00506
    00507         if (!fEnd)
    00508             return WMCSR_CANCEL;
    00509     }
    00510
    00511     return WMCSR_ALLOWSHUTDOWN;
    00512 }

BOOL xxxRegisterUserHungAppHandlers | ( | PFNW32ET | pfnW32EndTask,
|  | HANDLE | hEventWowExec
| ) |

Definition at line 565 of file kernel/exitwin.c.

References BOOL, ExEventObjectType, FALSE, gpwpiFirstWow, tagWOWPROCESSINFO::hEventWowExecClient, tagWOWPROCESSINFO::lpfnWowExitTask, NT_SUCCESS, NULL, ObReferenceObjectByHandle(), tagWOWPROCESSINFO::pEventWowExec, PpiCurrent, PWOWPROCESSINFO, tagPROCESSINFO::pwpi, tagWOWPROCESSINFO::pwpiNext, UserMode, and WOWPROCESSINFO.

    00568 {
    00569     BOOL   bRetVal;
    00570     PPROCESSINFO    ppi;
    00571     PWOWPROCESSINFO pwpi;
    00572
    00573     //
    00574     //  Allocate the per wow process info stuff
    00575     //  ensuring the memory is Zero init.
    00576     //
    00577     pwpi = (PWOWPROCESSINFO) UserAllocPoolWithQuotaZInit(
    00578             sizeof(WOWPROCESSINFO), TAG_WOWPROCESSINFO);
    00579
    00580     if (!pwpi)
    00581         return FALSE;
    00582
    00583     //
    00584     // Reference the WowExec event for kernel access
    00585     //
    00586     bRetVal = NT_SUCCESS(ObReferenceObjectByHandle(
    00587                  hEventWowExec,
    00588                  EVENT_ALL_ACCESS,
    00589                  *ExEventObjectType,
    00590                  UserMode,
    00591                  &pwpi->pEventWowExec,
    00592                  NULL
    00593                  ));
    00594
    00595     //
    00596     //  if sucess then intialize the pwpi, ppi structs
    00597     //  else free allocated memory
    00598     //
    00599     if (bRetVal) {
    00600         pwpi->hEventWowExecClient = hEventWowExec;
    00601         pwpi->lpfnWowExitTask = pfnW32EndTask;
    00602         ppi = PpiCurrent();
    00603         ppi->pwpi = pwpi;
    00604
    00605         // add to the list, order doesn't matter
    00606         pwpi->pwpiNext = gpwpiFirstWow;
    00607         gpwpiFirstWow  = pwpi;
    00608
    00609         }
    00610     else {
    00611         UserFreePool(pwpi);
    00612         }
    00613
    00614    return bRetVal;
    00615 }

## Variable Documentation

DWORD gdwLocks

| Definition at line 22 of file kernel/exitwin.c. Referenced by EndShutdown(), and InitiateShutdown().

DWORD gdwShutdownFlags

| Definition at line 23 of file kernel/exitwin.c. Referenced by EndShutdown(), and InitiateShutdown().

HANDLE gpidEndSession

| Definition at line 24 of file kernel/exitwin.c. Referenced by EndShutdown(), and InitiateShutdown().

PSECURITY_DESCRIPTOR gpsdInitWinSta

| Definition at line 26 of file kernel/exitwin.c. Referenced by InitCreateObjectDirectory(), InitSecurity(), and Win32kNtUserCleanup().

PWINDOWSTATION gpwinstaLogoff

| Definition at line 21 of file kernel/exitwin.c. Referenced by EndShutdown(), and InitiateShutdown().