|
|
/****************************** Module Header ******************************\
* Module Name: options.c * * Copyright (c) 1991, Microsoft Corporation * * Implementation of functions to support security options dialog. * * History: * 12-05-91 Davidc Created. \***************************************************************************/
#include "msgina.h"
#include "shtdnp.h"
#include <stdio.h>
#include <wchar.h>
#pragma hdrstop
#define CTRL_TASKLIST_SHELL
#define LPTSTR LPWSTR
#define BOOLIFY(expr) (!!(expr))
//
// Private prototypes
//
INT_PTR WINAPI OptionsDlgProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam );
BOOL OptionsDlgInit(HWND);
INT_PTR WINAPI EndWindowsSessionDlgProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam );
/******************************************************************************
* * HandleFailedDisconnect * * Tell the user why the disconnect from the current Logon failed. * * ENTRY: * hDlg (input) * This dialog's window handle. * SessionId (input) * The user's current SessionId. * * EXIT: * ******************************************************************************/
VOID HandleFailedDisconnect( HWND hDlg, ULONG SessionId, PGLOBALS pGlobals ) { DWORD Error; TCHAR Buffer1[MAX_STRING_BYTES] = TEXT(""); TCHAR Buffer2[MAX_STRING_BYTES]; TCHAR Buffer3[MAX_STRING_BYTES] = TEXT("");
Error = GetLastError(); switch (Error) {
default: LoadString( hDllInstance, IDS_MULTIUSER_UNEXPECTED_DISCONNECT_FAILURE, Buffer1, MAX_STRING_BYTES ); FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, Error, 0, Buffer3, MAX_STRING_BYTES, NULL );
_snwprintf(Buffer2, MAX_STRING_BYTES - 1, Buffer1, SessionId, Buffer3); Buffer2[MAX_STRING_BYTES - 1] = 0;
Buffer1[0] = 0; LoadString( hDllInstance, IDS_MULTIUSER_DISCONNECT_FAILED, Buffer1, MAX_STRING_BYTES );
TimeoutMessageBoxlpstr( hDlg, pGlobals, Buffer2, Buffer1, MB_OK | MB_ICONEXCLAMATION, TIMEOUT_CURRENT ); break; } }
/***************************************************************************\
* SecurityOptions * * Show the user the security options dialog and do what they ask. * * Returns: * MSGINA_DLG_SUCCESS if everything went OK and the user wants to continue * DLG_LOCK_WORKSTAION if the user chooses to lock the workstation * DLG_INTERRUPTED() - this is a set of possible interruptions (see winlogon.h) * MSGINA_DLG_FAILURE if the dialog cannot be brought up. * * History: * 12-09-91 Davidc Created. \***************************************************************************/
INT_PTR SecurityOptions( PGLOBALS pGlobals) { int Result; DWORD dwTimeOut;
dwTimeOut = OPTIONS_TIMEOUT;
// Bring the timeout to 30 sec if the SS timeout is less than 2 minutes.
if (OpenHKeyCurrentUser(pGlobals)) { HKEY hkeyUserControl; DWORD dwType ; DWORD cbData ; DWORD dwValue = 0; TCHAR szBuffer[11]; // Enough for a DWORD
// Get user preference
if (RegOpenKeyEx(pGlobals->UserProcessData.hCurrentUser, SCREENSAVER_KEY, 0, KEY_READ, &hkeyUserControl) == ERROR_SUCCESS) {
cbData = sizeof(szBuffer);
if (ERROR_SUCCESS == RegQueryValueEx( hkeyUserControl, TEXT("ScreenSaveTimeOut") , 0, &dwType, (LPBYTE)szBuffer, &cbData)) { if ((dwType == REG_SZ) && (cbData > 1) && (szBuffer[cbData / sizeof(TCHAR) - 1] == 0)) { dwValue = _wtol(szBuffer); } } RegCloseKey( hkeyUserControl ); }
// Overide by policy?
if (RegOpenKeyEx(pGlobals->UserProcessData.hCurrentUser, SCREENSAVER_POLICY_KEY, 0, KEY_READ, &hkeyUserControl) == ERROR_SUCCESS) {
cbData = sizeof(szBuffer);
if (ERROR_SUCCESS == RegQueryValueEx( hkeyUserControl, TEXT("ScreenSaveTimeOut") , 0, &dwType, (LPBYTE)szBuffer, &cbData)) { if ((dwType == REG_SZ) && (cbData > 1) && (szBuffer[cbData / sizeof(TCHAR) - 1] == 0)) { dwValue = _wtol(szBuffer); } } RegCloseKey( hkeyUserControl ); }
if (dwValue <= OPTIONS_TIMEOUT) { dwTimeOut = 30; }
CloseHKeyCurrentUser(pGlobals); }
pWlxFuncs->WlxSetTimeout(pGlobals->hGlobalWlx, dwTimeOut);
Result = pWlxFuncs->WlxDialogBoxParam( pGlobals->hGlobalWlx, hDllInstance, (LPTSTR)IDD_OPTIONS_DIALOG, NULL, OptionsDlgProc, (LPARAM) pGlobals);
if (Result == WLX_DLG_INPUT_TIMEOUT) { Result = MSGINA_DLG_SUCCESS; }
return(Result); }
/***************************************************************************\
* * FUNCTION: OptionsDlgProc * * PURPOSE: Processes messages for Security options dialog * \***************************************************************************/
INT_PTR WINAPI OptionsDlgProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) { PGLOBALS pGlobals = (PGLOBALS)GetWindowLongPtr(hDlg, GWLP_USERDATA); INT_PTR Result; HANDLE UserHandle; NTSTATUS Status; BOOL EnableResult; BOOL ControlKey;
switch (message) {
case WM_INITDIALOG: SetWindowLongPtr(hDlg, GWLP_USERDATA, lParam);
if (!OptionsDlgInit(hDlg)) { EndDialog(hDlg, MSGINA_DLG_FAILURE); } return(TRUE);
case WLX_WM_SAS:
//
// If this is someone hitting C-A-D, swallow it.
//
if (wParam == WLX_SAS_TYPE_CTRL_ALT_DEL) { return(TRUE); }
//
// Other SAS's (like timeout), return FALSE and let winlogon
// deal with it.
//
DebugLog((DEB_TRACE, "Received SAS event %d, which we're letting winlogon cope with\n", wParam)); return(FALSE);
case WM_COMMAND:
ControlKey = (GetKeyState(VK_LCONTROL) < 0) || (GetKeyState(VK_RCONTROL) < 0) ;
switch (LOWORD(wParam)) {
case IDCANCEL: EndDialog(hDlg, MSGINA_DLG_SUCCESS); return TRUE;
case IDD_OPTIONS_CHANGEPWD: Result = ChangePassword(hDlg, pGlobals, pGlobals->UserName, pGlobals->Domain, CHANGEPWD_OPTION_ALL );
if (DLG_INTERRUPTED(Result)) { EndDialog(hDlg, Result); } return(TRUE);
case IDD_OPTIONS_LOCK: EndDialog(hDlg, MSGINA_DLG_LOCK_WORKSTATION); return(TRUE);
case IDD_OPTIONS_LOGOFF:
if (ControlKey) { Result = TimeoutMessageBox(hDlg, pGlobals, IDS_LOGOFF_LOSE_CHANGES, IDS_LOGOFF_TITLE, MB_OKCANCEL | MB_DEFBUTTON2 | MB_ICONSTOP, TIMEOUT_CURRENT);
if (Result == MSGINA_DLG_SUCCESS) { EndDialog(hDlg, MSGINA_DLG_FORCE_LOGOFF); } } else {
//
// Confirm the user really knows what they're doing.
//
Result = pWlxFuncs->WlxDialogBoxParam( pGlobals->hGlobalWlx, hDllInstance, MAKEINTRESOURCE(IDD_LOGOFFWINDOWS_DIALOG), hDlg, EndWindowsSessionDlgProc, (LPARAM)pGlobals);
if (Result == MSGINA_DLG_SUCCESS) { EndDialog(hDlg, MSGINA_DLG_USER_LOGOFF); } }
return(TRUE);
case IDD_OPTIONS_SHUTDOWN:
//
// If they held down Ctrl while selecting shutdown - then
// we'll do a quick and dirty reboot.
// i.e. we skip the call to ExitWindows
//
if ( ControlKey && TestUserPrivilege(pGlobals->UserProcessData.UserToken, SE_SHUTDOWN_PRIVILEGE)) { //
// Check they know what they're doing
//
Result = TimeoutMessageBox(hDlg, pGlobals, IDS_REBOOT_LOSE_CHANGES, IDS_EMERGENCY_SHUTDOWN, MB_OKCANCEL | MB_DEFBUTTON2 | MB_ICONSTOP, TIMEOUT_CURRENT); if (Result == MSGINA_DLG_SUCCESS) { //
// Impersonate the user for the shutdown call
//
UserHandle = ImpersonateUser( &pGlobals->UserProcessData, NULL ); ASSERT(UserHandle != NULL);
if ( UserHandle ) {
//
// Enable the shutdown privilege
// This should always succeed - we are either system or a user who
// successfully passed the privilege check in ExitWindowsEx.
//
EnableResult = EnablePrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE); ASSERT(EnableResult);
//
// Do the final system shutdown pass (reboot). Note, if
// the privilege was not enabled, the API will reject this
// call.
//
Status = NtShutdownSystem(ShutdownReboot); } }
if (Result != MSGINA_DLG_FAILURE) { EndDialog(hDlg, Result); }
return(TRUE); }
//
// This is a normal shutdown request
//
// Check they know what they're doing and find
// out if they want to reboot too.
//
Result = WinlogonShutdownDialog(hDlg, pGlobals, 0);
// Pre-filter the Disconnect option and handle
// it now since it may fail
if (Result == MSGINA_DLG_DISCONNECT) { if ( pWlxFuncs->WlxDisconnect() ) { Result = MSGINA_DLG_SUCCESS; } else { HandleFailedDisconnect(hDlg, pGlobals->MuGlobals.SessionId, pGlobals); Result = MSGINA_DLG_FAILURE; } }
if (Result != MSGINA_DLG_FAILURE) { EndDialog(hDlg, Result); }
return(TRUE);
case IDD_OPTIONS_TASKLIST:
EndDialog(hDlg, MSGINA_DLG_TASKLIST);
//
// Tickle the messenger so it will display any queue'd messages.
// (This call is a kind of NoOp).
//
NetMessageNameDel(NULL,L"");
return(TRUE); break;
}
case WM_ERASEBKGND: return PaintBranding(hDlg, (HDC)wParam, 0, FALSE, FALSE, COLOR_BTNFACE);
case WM_QUERYNEWPALETTE: return BrandingQueryNewPalete(hDlg);
case WM_PALETTECHANGED: return BrandingPaletteChanged(hDlg, (HWND)wParam);
}
// We didn't process the message
return(FALSE); }
/****************************************************************************
FUNCTION: OptionsDlgInit
PURPOSE: Handles initialization of security options dialog
RETURNS: TRUE on success, FALSE on failure ****************************************************************************/
BOOL OptionsDlgInit( HWND hDlg) { PGLOBALS pGlobals = (PGLOBALS)GetWindowLongPtr(hDlg, GWLP_USERDATA); TCHAR Buffer1[MAX_STRING_BYTES] = TEXT(""); TCHAR Buffer2[MAX_STRING_BYTES]; BOOL Result; DWORD dwValue, dwType; HKEY hkeyPolicy; DWORD cbData; HANDLE hImpersonateUser = NULL; USHORT Flags = FT_TIME|FT_DATE; LCID locale;
SetWelcomeCaption( hDlg );
//
// Set the logon info text
//
if (pGlobals->Domain[0] == TEXT('\0') ) {
//
// there is no domain name
//
if ( lstrlen(pGlobals->UserFullName) == 0) {
//
// There is no full name
//
LoadString(hDllInstance, IDS_LOGON_EMAIL_NAME_NFN_INFO, Buffer1, MAX_STRING_BYTES);
_snwprintf(Buffer2, sizeof(Buffer2)/sizeof(TCHAR) - 1, Buffer1, pGlobals->UserName);
} else {
LoadString(hDllInstance, IDS_LOGON_EMAIL_NAME_INFO, Buffer1, MAX_STRING_BYTES);
_snwprintf(Buffer2, sizeof(Buffer2)/sizeof(TCHAR), Buffer1, pGlobals->UserFullName, pGlobals->UserName);
}
} else { if ( lstrlen(pGlobals->UserFullName) == 0) {
//
// There is no full name
//
LoadString(hDllInstance, IDS_LOGON_NAME_NFN_INFO, Buffer1, MAX_STRING_BYTES);
_snwprintf(Buffer2, sizeof(Buffer2)/sizeof(TCHAR), Buffer1, pGlobals->Domain, pGlobals->UserName);
} else {
LoadString(hDllInstance, IDS_LOGON_NAME_INFO, Buffer1, MAX_STRING_BYTES);
_snwprintf(Buffer2, sizeof(Buffer2)/sizeof(TCHAR), Buffer1, pGlobals->UserFullName, pGlobals->Domain, pGlobals->UserName);
} }
// Taking care of all _snwprintf(Buffer2 above
Buffer2[sizeof(Buffer2)/sizeof(TCHAR) - 1] = 0;
SetDlgItemText(hDlg, IDD_OPTIONS_LOGON_NAME_INFO, Buffer2);
//
// Set the logon time/date - but do it as the logged on user
//
hImpersonateUser = ImpersonateUser(&pGlobals->UserProcessData, NULL);
locale = GetUserDefaultLCID();
if (((PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_ARABIC) || (PRIMARYLANGID(LANGIDFROMLCID(locale)) == LANG_HEBREW))) { // Get the real item windows ExStyle.
HWND hWnd = GetDlgItem(hDlg, IDD_OPTIONS_LOGON_DATE); DWORD dwExStyle = GetWindowLong(hWnd, GWL_EXSTYLE); if ((BOOLIFY(dwExStyle & WS_EX_RTLREADING)) != (BOOLIFY(dwExStyle & WS_EX_LAYOUTRTL))) Flags |= FT_RTL; else Flags |= FT_LTR; }
Result = FormatTime(&pGlobals->LogonTime, Buffer1, sizeof(Buffer1) / sizeof(Buffer1[0]), Flags); if (hImpersonateUser) { StopImpersonating(hImpersonateUser); }
ASSERT(Result); SetDlgItemText(hDlg, IDD_OPTIONS_LOGON_DATE, Buffer1);
//
// Check if DisableLockWorkstation is set for the entire machine
//
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WINLOGON_KEY, 0, KEY_READ, &hkeyPolicy) == ERROR_SUCCESS) { dwValue = 0; cbData = sizeof(dwValue); if ((ERROR_SUCCESS == RegQueryValueEx(hkeyPolicy, DISABLE_LOCK_WKSTA, 0, &dwType, (LPBYTE)&dwValue, &cbData)) && (REG_DWORD == dwType)) { if (dwValue) { EnableDlgItem(hDlg, IDD_OPTIONS_LOCK, FALSE); } }
RegCloseKey(hkeyPolicy); }
//
// Smart card only users can't change the password
//
if (pGlobals->Profile && (pGlobals->Profile->UserFlags & UF_SMARTCARD_REQUIRED)) { EnableDlgItem(hDlg, IDD_OPTIONS_CHANGEPWD, FALSE); }
//
// Check for policy and then disable corresponding options
//
if (OpenHKeyCurrentUser(pGlobals)) {
if (RegOpenKeyEx(pGlobals->UserProcessData.hCurrentUser, WINLOGON_POLICY_KEY, 0, KEY_READ, &hkeyPolicy) == ERROR_SUCCESS) { dwValue = 0; cbData = sizeof(dwValue); if ((ERROR_SUCCESS == RegQueryValueEx(hkeyPolicy, DISABLE_LOCK_WKSTA, 0, &dwType, (LPBYTE)&dwValue, &cbData)) && (REG_DWORD == dwType)) { if (dwValue) { EnableDlgItem(hDlg, IDD_OPTIONS_LOCK, FALSE); } }
dwValue = 0; cbData = sizeof(dwValue); if ((ERROR_SUCCESS == RegQueryValueEx(hkeyPolicy, DISABLE_TASK_MGR, 0, &dwType, (LPBYTE)&dwValue, &cbData)) && (REG_DWORD == dwType)) { if (dwValue) { EnableDlgItem(hDlg, IDD_OPTIONS_TASKLIST, FALSE); ShowDlgItem(hDlg, IDD_OPTIONS_TASKMGR_TEXT, FALSE); } }
dwValue = 0; cbData = sizeof(dwValue); if ((ERROR_SUCCESS == RegQueryValueEx(hkeyPolicy, DISABLE_CHANGE_PASSWORD, 0, &dwType, (LPBYTE)&dwValue, &cbData)) && (REG_DWORD == dwType)) { if (dwValue) { EnableDlgItem(hDlg, IDD_OPTIONS_CHANGEPWD, FALSE); } }
RegCloseKey(hkeyPolicy); }
if (RegOpenKeyEx(pGlobals->UserProcessData.hCurrentUser, EXPLORER_POLICY_KEY, 0, KEY_READ, &hkeyPolicy) == ERROR_SUCCESS) { dwValue = 0; cbData = sizeof(dwValue); if ((ERROR_SUCCESS == RegQueryValueEx(hkeyPolicy, NOLOGOFF, 0, &dwType, (LPBYTE)&dwValue, &cbData)) && (REG_DWORD == dwType)) { if (dwValue) { EnableDlgItem(hDlg, IDD_OPTIONS_LOGOFF, FALSE); } }
dwValue = 0; cbData = sizeof(dwValue);
if ((ERROR_SUCCESS != RegQueryValueEx(hkeyPolicy, NOCLOSE, 0, &dwType, (LPBYTE)&dwValue, &cbData)) || (REG_DWORD != dwType)) { dwValue = 0; }
//
// If this is not the system console, check the appropriate key in registry
//
if ( !g_Console ) { if (!TestUserPrivilege(pGlobals->UserProcessData.UserToken, SE_SHUTDOWN_PRIVILEGE)) { DWORD dwVal = 0;
cbData = sizeof(dwVal); if ((ERROR_SUCCESS == RegQueryValueEx(hkeyPolicy, NODISCONNECT, 0, &dwType, (LPBYTE)&dwVal, &cbData)) && (REG_DWORD == dwType)) { dwValue = dwVal; } } }
if (dwValue) { EnableDlgItem(hDlg, IDD_OPTIONS_SHUTDOWN, FALSE); } RegCloseKey(hkeyPolicy); }
CloseHKeyCurrentUser(pGlobals); }
// Position ourselves nicely
SizeForBranding(hDlg, FALSE); CentreWindow(hDlg);
return TRUE; }
/***************************************************************************\
* FUNCTION: EndWindowsSessionDlgProc * * PURPOSE: Processes messages for Logging off Windows Nt confirmation dialog * * RETURNS: MSGINA_DLG_SUCCESS - The user wants to logoff. * MSGINA_DLG_FAILURE - The user doesn't want to logoff. * DLG_INTERRUPTED() - a set defined in winlogon.h * * HISTORY: * * 05-17-92 Davidc Created. * \***************************************************************************/
INT_PTR WINAPI EndWindowsSessionDlgProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) {
static HICON hIcon = NULL; switch (message) {
case WM_INITDIALOG: {
SetWindowLongPtr(hDlg, GWLP_USERDATA, lParam);
// Load the 48 x 48 version of the logoff icon
if( NULL == hIcon ) { hIcon = LoadImage (hDllInstance, MAKEINTRESOURCE(IDI_STLOGOFF), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR); }
if (hIcon) { SendDlgItemMessage (hDlg, IDD_LOGOFFICON, STM_SETICON, (WPARAM) hIcon, 0); }
// Position ourselves nicely
CentreWindow(hDlg);
} return(TRUE);
case WLX_WM_SAS:
//
// If this is someone hitting C-A-D, swallow it.
//
if (wParam == WLX_SAS_TYPE_CTRL_ALT_DEL) { return(TRUE); }
//
// Other SAS's (like timeout), return FALSE and let winlogon
// deal with it.
//
return(FALSE);
case WM_COMMAND: switch (LOWORD(wParam)) {
case IDOK: EndDialog(hDlg, MSGINA_DLG_SUCCESS); return(TRUE);
case IDCANCEL: EndDialog(hDlg, MSGINA_DLG_FAILURE); return(TRUE); } break; case WM_DESTROY: if (hIcon) { DestroyIcon(hIcon); hIcon = NULL; } break;
}
// We didn't process the message
return(FALSE); }
|