Exemple #1
0
int WINAPI
wWinMain(IN HINSTANCE hInst,
         IN HINSTANCE hPrevInstance,
         IN LPWSTR lpszCmdLine,
         IN int nCmdShow)
{
    STATE State;

    hInstance = hInst;

    SetUserSettings();

    if (IsLiveCD())
    {
        State.NextPage = LOCALEPAGE;
        State.Run = SHELL;
    }
    else
    {
        State.NextPage = DONE;
        State.Run = SHELL;
    }

    if (State.NextPage != DONE)
    {
        RunLiveCD(&State);
    }

    if (State.Run == SHELL)
    {
        StartShell();
        NotifyLogon();
    }
    else if (State.Run == INSTALLER)
    {
        StartInstaller();
    }

    return 0;
}
Exemple #2
0
int WINAPI
wWinMain(IN HINSTANCE hInst,
         IN HINSTANCE hPrevInstance,
         IN LPWSTR lpszCmdLine,
         IN int nCmdShow)
{
    BOOL bIsLiveCD, Success = TRUE;
    STATE State;

    hInstance = hInst;

    bIsLiveCD = IsLiveCD();

Restart:
    SetUserSettings();

    if (bIsLiveCD)
    {
        State.NextPage = LOCALEPAGE;
        State.Run = SHELL;
    }
    else
    {
        State.NextPage = DONE;
        State.Run = SHELL;
    }

    if (State.NextPage != DONE) // && bIsLiveCD
    {
        RunLiveCD(&State);
    }

    switch (State.Run)
    {
        case SHELL:
            Success = StartShell();
            if (Success)
                NotifyLogon();
            break;

        case INSTALLER:
            Success = StartInstaller();
            break;

        case REBOOT:
        {
            EnablePrivilege(SE_SHUTDOWN_NAME, TRUE);
            ExitWindowsEx(EWX_REBOOT, 0);
            EnablePrivilege(SE_SHUTDOWN_NAME, FALSE);
            Success = TRUE;
            break;
        }

        default:
            Success = FALSE;
            break;
    }

    /*
     * In LiveCD mode, go back to the main menu if we failed
     * to either start the shell or the installer.
     */
    if (bIsLiveCD && !Success)
        goto Restart;

    return 0;
}
Exemple #3
0
NTSTATUS InitiateShutdown(
    PETHREAD Thread,
    PULONG lpdwFlags)
{
    static PRIVILEGE_SET psShutdown = {
        1, PRIVILEGE_SET_ALL_NECESSARY, { SE_SHUTDOWN_PRIVILEGE, 0 }
    };
    PEPROCESS Process;
    LUID luidCaller;
    LUID luidSystem = SYSTEM_LUID;
    PPROCESSINFO ppi;
    PWINDOWSTATION pwinsta;
    HWINSTA hwinsta;
    PTHREADINFO ptiClient;
    NTSTATUS Status;
    DWORD dwFlags;

    /*
     * Find out the callers sid. Only want to shutdown processes in the
     * callers sid.
     */
    Process = THREAD_TO_PROCESS(Thread);
    ptiClient = PtiFromThread(Thread);
    Status = GetProcessLuid(Thread, &luidCaller);

    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    /*
     * Set the system flag if the caller is a system process.
     * Winlogon uses this to determine in which context to perform
     * a shutdown operation.
     */
    dwFlags = *lpdwFlags;
    if (RtlEqualLuid(&luidCaller, &luidSystem)) {
        dwFlags |= EWX_SYSTEM_CALLER;
    } else {
        dwFlags &= ~EWX_SYSTEM_CALLER;
    }

    /*
     * Find a windowstation.  If the process does not have one
     * assigned, use the standard one.
     */
    ppi = PpiFromProcess(Process);
    if (ppi == NULL) {
        /*
         * We ran into a case where the thread was terminated and had already
         * been cleaned up by USER.  Thus, the ppi and ptiClient was NULL.
         */
        return STATUS_INVALID_HANDLE;
    }

    pwinsta = ppi->rpwinsta;
    hwinsta = ppi->hwinsta;

    /*
     * If we're not being called by Winlogon, validate the call and
     * notify the logon process to do the actual shutdown.
     */
    if (Thread->Cid.UniqueProcess != gpidLogon) {
        dwFlags &= ~EWX_WINLOGON_CALLER;
        *lpdwFlags = dwFlags;

        if (pwinsta == NULL) {
#ifndef LATER
            return STATUS_INVALID_HANDLE;
#else
            hwinsta = ppi->pOpenObjectTable[HI_WINDOWSTATION].h;
            if (hwinsta == NULL) {
                return STATUS_INVALID_HANDLE;
            }
            pwinsta = (PWINDOWSTATION)ppi->pOpenObjectTable[HI_WINDOWSTATION].phead;
#endif
        }

        /*
         * Check security first - does this thread have access?
         */
        if (!RtlAreAllAccessesGranted(ppi->amwinsta, WINSTA_EXITWINDOWS)) {
            return STATUS_ACCESS_DENIED;
        }

        /*
         * If the client requested shutdown, reboot, or poweroff they must have
         * the shutdown privilege.
         */
        if (dwFlags & EWX_SHUTDOWN) {
            if (!IsPrivileged(&psShutdown) ) {
                return STATUS_PRIVILEGE_NOT_HELD;
            }
        } else {

            /*
             * If this is a non-IO windowstation and we are not shutting down,
             * fail the call.
             */
            if (pwinsta->dwFlags & WSF_NOIO) {
                return STATUS_INVALID_DEVICE_REQUEST;
            }
        }
    }

    /*
     * Is there a shutdown already in progress?
     */
    if (dwThreadEndSession != 0) {
        DWORD dwNew;

        /*
         * Calculate new flags
         */
        dwNew = dwFlags & OPTIONMASK & (~gdwShutdownFlags);

        /*
         * Should we override the other shutdown?  Make sure
         * winlogon does not recurse.
         */
        if (dwNew && (DWORD)PsGetCurrentThread()->Cid.UniqueThread !=
                dwThreadEndSession) {
            /*
             * Only one windowstation can be logged off at a time.
             */
            if (!(dwFlags & EWX_SHUTDOWN) &&
                    pwinsta != gpwinstaLogoff) {
                return STATUS_DEVICE_BUSY;
            }

            /*
             * Set the new flags
             */
            gdwShutdownFlags = dwFlags;

            if (dwNew & EWX_FORCE) {
                return STATUS_RETRY;
            } else {
                return STATUS_PENDING;
            }
        } else {
            /*
             * Don't override
             */
            return STATUS_PENDING;
        }
    }

    /*
     * If the caller is not winlogon, signal winlogon to start
     * the real shutdown.
     */
    if (Thread->Cid.UniqueProcess != gpidLogon) {
        if (dwFlags & EWX_NOTIFY) {
            if (ptiClient && ptiClient->TIF_flags & TIF_16BIT)
                gptiShutdownNotify = ptiClient;
            dwFlags &= ~EWX_NOTIFY;
            *lpdwFlags = dwFlags;
        }

        if (NotifyLogon(pwinsta, &luidCaller, dwFlags))
            return STATUS_PENDING;
        else if (ptiClient && ptiClient->cWindows)
            return STATUS_CANT_WAIT;
    }

    /*
     * Mark this thread as the one that is currently processing
     * exit windows, and set the global saying someone is exiting
     */
    dwFlags |= EWX_WINLOGON_CALLER;
    *lpdwFlags = dwFlags;
    gdwShutdownFlags = dwFlags;

    dwThreadEndSession = (DWORD)PsGetCurrentThread()->Cid.UniqueThread;
    gpwinstaLogoff = pwinsta;
    pwinsta->luidEndSession = luidCaller;

    /*
     * Lock the windowstation to prevent apps from starting
     * while we're doing shutdown processing.
     */
    gdwLocks = pwinsta->dwFlags & (WSF_SWITCHLOCK | WSF_OPENLOCK);
    pwinsta->dwFlags |= (WSF_OPENLOCK | WSF_SHUTDOWN);

    return STATUS_SUCCESS;
}
Exemple #4
0
NTSTATUS EndShutdown(
    PETHREAD Thread,
    NTSTATUS StatusShutdown)
{
    PWINDOWSTATION pwinsta = gpwinstaLogoff;
    PDESKTOP pdesk;
    LUID luidCaller;

    UserAssert(gpwinstaLogoff);

    gpwinstaLogoff = NULL;
    dwThreadEndSession = 0;
    pwinsta->dwFlags &= ~WSF_SHUTDOWN;

    if (!NT_SUCCESS(GetProcessLuid(Thread, &luidCaller))) {
        luidCaller = RtlConvertUlongToLuid(0);     // null luid
    }

    if (!NT_SUCCESS(StatusShutdown)) {

        /*
         * We need to notify the process that called ExitWindows that
         * the logoff was aborted.
         */
        if (gptiShutdownNotify) {
            _PostThreadMessage(gptiShutdownNotify, WM_ENDSESSION, FALSE, 0);
            gptiShutdownNotify = NULL;
        }

        /*
         * Reset the windowstation lock flags so apps can start
         * again.
         */
        pwinsta->dwFlags =
                (pwinsta->dwFlags & ~WSF_OPENLOCK) |
                gdwLocks;

        return STATUS_SUCCESS;
    }

    gptiShutdownNotify = NULL;

    /*
     * If logoff is occuring for the user set by winlogon, perform
     * the normal logoff cleanup.  Otherwise, clear the open lock
     * and continue.
     */
    if (((pwinsta->luidUser.LowPart != 0) || (pwinsta->luidUser.HighPart != 0)) &&
            RtlEqualLuid(&pwinsta->luidUser, &luidCaller)) {

        /*
         * Save the current user's NumLock state
         */
        if (FastOpenProfileUserMapping()) {
            RegisterPerUserKeyboardIndicators();
            FastCloseProfileUserMapping();
        }

        /*
         * Zero out the free blocks in all desktop heaps.
         */
        for (pdesk = pwinsta->rpdeskList; pdesk != NULL; pdesk = pdesk->rpdeskNext) {
            RtlZeroHeap(pdesk->hheapDesktop, 0);
        }

        /*
         * Logoff/shutdown was successful. In case this is a logoff, remove
         * everything from the clipboard so the next logged on user can't get
         * at this stuff.
         */
        ForceEmptyClipboard(pwinsta);

        /*
         * Destroy all non-pinned atoms in the global atom table.  User can't
         * create pinned atoms.  Currently only the OLE atoms are pinned.
         */
        RtlEmptyAtomTable(pwinsta->pGlobalAtomTable, FALSE);

        // this code path is hit only on logoff and also on shutdown
        // We do not want to unload fonts twice when we attempt shutdown
        // so we mark that the fonts have been unloaded at a logoff time

        if (bFontsAreLoaded) {
            LeaveCrit();
            GreRemoveAllButPermanentFonts();
            EnterCrit();
            bFontsAreLoaded = FALSE;
        }
    } else {
        pwinsta->dwFlags &= ~WSF_OPENLOCK;
    }

    /*
     * Tell winlogon that we successfully shutdown/logged off.
     */
    NotifyLogon(pwinsta, &luidCaller, gdwShutdownFlags);

    return STATUS_SUCCESS;
}