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; }
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; }
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; }
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; }