mark.
gina\winlogon\sas.c
LRESULT SASWndProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
//...
switch (message)
{
//...
case WM_LOGONNOTIFY: // A private notification from Windows
DebugLog((DEB_TRACE_SAS, "LOGONNOTIFY message %d\n", wParam ));
switch (wParam)
{
//...
case LOGON_RESTARTSHELL:
//
// Restart the shell after X seconds
//
// We don't restart the shell for the following conditions:
//
// 1) No one is logged on
// 2) We are in the process of logging off
// (logoffflags will be non-zero)
// 3) The shell exiting gracefully
// (Exit status is in lParam. 1 = graceful)
// 4) A new user has logged on after the request
// to restart the shell.
// (in the case of autoadminlogon, the new
// user could be logged on before the restart
// request comes through).
//
if (!pTerm->UserLoggedOn ||
pTerm->LogoffFlags ||
(lParam == 1) ||
(pTerm->TickCount > (DWORD)GetMessageTime())) {
break;
}
SetTimer (hwnd, SHELL_RESTART_TIMER_ID, 2000, NULL);
break;
//...
}
return(0);
//...
case WM_TIMER:
{
LONG lResult;
HKEY hKey;
BOOL bRestart = TRUE;
DWORD dwType, dwSize;
//
// Restart the shell
//
if (wParam != SHELL_RESTART_TIMER_ID) {
break;
}
KillTimer (hwnd, SHELL_RESTART_TIMER_ID);
//
// Check if we should restart the shell
//
lResult = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
WINLOGON_KEY,
0,
KEY_READ,
&hKey);
if (lResult == ERROR_SUCCESS) {
dwSize = sizeof(bRestart);
RegQueryValueEx (hKey,
TEXT("AutoRestartShell"),
NULL,
&dwType,
(LPBYTE) &bRestart,
&dwSize);
RegCloseKey (hKey);
}
if (!pTerm->UserLoggedOn) {
bRestart = FALSE;
}
if (bRestart) {
PWCH pchData;
PWSTR pszTok;
DebugLog((DEB_TRACE, "Restarting user's shell.\n"));
pchData = AllocAndGetPrivateProfileString(APPLICATION_NAME,
SHELL_KEY,
TEXT("explorer.exe"),
NULL);
if (!pchData) {
break;
}
wsprintfW (szDesktop, L"%s\\%s", pTerm->pWinStaWinlogon->lpWinstaName,
APPLICATION_DESKTOP_NAME);
pszTok = wcstok(pchData, TEXT(","));
while (pszTok)
{
if (*pszTok == TEXT(' '))
{
while (*pszTok++ == TEXT(' '))
;
}
if (StartApplication(pTerm,
szDesktop,
pTerm->pWinStaWinlogon->UserProcessData.pEnvironment,
pszTok)) {
ReportWinlogonEvent(pTerm,
EVENTLOG_INFORMATION_TYPE,
EVENT_SHELL_RESTARTED,
0,
NULL,
1,
pszTok);
}
pszTok = wcstok(NULL, TEXT(","));
}
Free(pchData);
}
}
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0L;
}