mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
666 lines
20 KiB
666 lines
20 KiB
/****************************** 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"
|
|
#pragma hdrstop
|
|
|
|
#include <stdio.h>
|
|
#include <wchar.h>
|
|
|
|
#if DBCS_IME // by eichim, 23-Jun-92
|
|
extern BOOL bLoggedonIME;
|
|
#endif
|
|
|
|
#define CTRL_TASKLIST_SHELL
|
|
|
|
#define LPTSTR LPWSTR
|
|
//
|
|
// Private prototypes
|
|
//
|
|
|
|
BOOL WINAPI
|
|
OptionsDlgProc(
|
|
HWND hDlg,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
);
|
|
|
|
BOOL OptionsDlgInit(HWND);
|
|
|
|
BOOL WINAPI
|
|
ShutdownQueryDlgProc(
|
|
HWND hDlg,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
);
|
|
|
|
BOOL WINAPI
|
|
EndWindowsSessionDlgProc(
|
|
HWND hDlg,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
);
|
|
|
|
|
|
|
|
|
|
/***************************************************************************\
|
|
* 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.
|
|
\***************************************************************************/
|
|
|
|
DLG_RETURN_TYPE
|
|
SecurityOptions(
|
|
PGLOBALS pGlobals)
|
|
{
|
|
int Result;
|
|
|
|
pWlxFuncs->WlxSetTimeout(hGlobalWlx, OPTIONS_TIMEOUT);
|
|
|
|
Result = pWlxFuncs->WlxDialogBoxParam( hGlobalWlx,
|
|
hDllInstance,
|
|
(LPTSTR)IDD_OPTIONS_DIALOG,
|
|
NULL,
|
|
OptionsDlgProc,
|
|
(LONG)pGlobals);
|
|
|
|
if (Result == WLX_DLG_INPUT_TIMEOUT)
|
|
{
|
|
Result = MSGINA_DLG_SUCCESS;
|
|
}
|
|
|
|
return(Result);
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* FUNCTION: OptionsDlgProc
|
|
*
|
|
* PURPOSE: Processes messages for Security options dialog
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL WINAPI
|
|
OptionsDlgProc(
|
|
HWND hDlg,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
PGLOBALS pGlobals = (PGLOBALS)GetWindowLong(hDlg, GWL_USERDATA);
|
|
DLG_RETURN_TYPE Result;
|
|
HANDLE UserHandle;
|
|
NTSTATUS Status;
|
|
BOOL EnableResult, IgnoreResult;
|
|
BOOL ControlKey;
|
|
|
|
|
|
switch (message) {
|
|
|
|
case WM_INITDIALOG:
|
|
SetWindowLong(hDlg, GWL_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,
|
|
TRUE);
|
|
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,
|
|
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( hGlobalWlx,
|
|
hDllInstance,
|
|
(LPTSTR)IDD_END_WINDOWS_SESSION,
|
|
hDlg,
|
|
EndWindowsSessionDlgProc,
|
|
(LONG)pGlobals);
|
|
|
|
if (Result == MSGINA_DLG_SUCCESS)
|
|
{
|
|
EndDialog(hDlg, MSGINA_DLG_USER_LOGOFF);
|
|
}
|
|
}
|
|
|
|
return(TRUE);
|
|
|
|
|
|
|
|
case IDD_OPTIONS_SHUTDOWN:
|
|
|
|
|
|
if (!TestUserPrivilege(pGlobals, SE_SHUTDOWN_PRIVILEGE))
|
|
{
|
|
|
|
//
|
|
// We don't have permission to shutdown
|
|
//
|
|
|
|
Result = TimeoutMessageBox(hDlg,
|
|
IDS_NO_PERMISSION_SHUTDOWN,
|
|
IDS_WINDOWS_MESSAGE,
|
|
MB_OK | MB_ICONSTOP,
|
|
TIMEOUT_CURRENT);
|
|
if (DLG_INTERRUPTED(Result))
|
|
{
|
|
EndDialog(hDlg, Result);
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// The user has the privilege to 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 )
|
|
{
|
|
|
|
//
|
|
// Check they know what they're doing
|
|
//
|
|
|
|
Result = TimeoutMessageBox(hDlg,
|
|
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);
|
|
|
|
//
|
|
// 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)
|
|
//
|
|
|
|
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 = pWlxFuncs->WlxDialogBoxParam( hGlobalWlx,
|
|
hDllInstance,
|
|
(LPTSTR)IDD_SHUTDOWN_QUERY,
|
|
hDlg,
|
|
ShutdownQueryDlgProc,
|
|
(LONG)pGlobals);
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 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)GetWindowLong(hDlg, GWL_USERDATA);
|
|
TCHAR Buffer1[MAX_STRING_BYTES];
|
|
TCHAR Buffer2[MAX_STRING_BYTES];
|
|
BOOL Result;
|
|
|
|
SetWelcomeCaption( hDlg );
|
|
|
|
//
|
|
// Set the logon info text
|
|
//
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
SetDlgItemText(hDlg, IDD_OPTIONS_LOGON_NAME_INFO, Buffer2);
|
|
|
|
//
|
|
// Set the logon time/date
|
|
//
|
|
Result = FormatTime(&pGlobals->LogonTime, Buffer1, sizeof(Buffer1), FT_TIME|FT_DATE);
|
|
ASSERT(Result);
|
|
SetDlgItemText(hDlg, IDD_OPTIONS_LOGON_DATE, Buffer1);
|
|
|
|
// Position ourselves nicely
|
|
CentreWindow(hDlg);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* FUNCTION: ShutdownQueryDlgProc
|
|
*
|
|
* PURPOSE: Processes messages for shutdown confirmation dialog
|
|
*
|
|
* RETURNS: DLG_SHUTDOWN_FLAG - The user wants to shutdown.
|
|
* DLG_POWEROFF_FLAG - The user wants to shutdown and power off.
|
|
* DLG_REBOOT_FLAG - The user wants to shutdown and reboot.
|
|
* MSGINA_DLG_FAILURE - The user doesn't want to shutdown
|
|
* DLG_INTERRUPTED() - a set defined in winlogon.h
|
|
*
|
|
* HISTORY:
|
|
*
|
|
* 05-17-92 Davidc Created.
|
|
* 10-04-93 Johannec Add poweroff option.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL WINAPI
|
|
ShutdownQueryDlgProc(
|
|
HWND hDlg,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
static DWORD dwShutdown = 1;
|
|
static HKEY hkeyShutdown = NULL;
|
|
int nResult;
|
|
DWORD cbData;
|
|
DWORD dwDisposition;
|
|
PGLOBALS pGlobals;
|
|
|
|
switch (message)
|
|
{
|
|
|
|
case WM_INITDIALOG:
|
|
{
|
|
DWORD dwType;
|
|
BOOL bPowerdown;
|
|
|
|
SetWindowLong(hDlg, GWL_USERDATA, lParam);
|
|
|
|
//
|
|
// Check if this computer can be powered off thru software. If so then
|
|
// an additional checkbox for power off will appear on shutdown dialogs.
|
|
//
|
|
bPowerdown = GetProfileInt(APPLICATION_NAME, POWER_DOWN_AFTER_SHUTDOWN, 0);
|
|
if (!bPowerdown)
|
|
{
|
|
ShowWindow(GetDlgItem(hDlg, IDD_POWEROFF), SW_HIDE);
|
|
EnableWindow( GetDlgItem( hDlg, IDD_POWEROFF), FALSE );
|
|
ShowWindow(GetDlgItem(hDlg, IDOK2), SW_HIDE);
|
|
ShowWindow(GetDlgItem(hDlg, IDCANCEL2), SW_HIDE);
|
|
SendMessage(hDlg, DM_SETDEFID, IDOK, 0);
|
|
}
|
|
else
|
|
{
|
|
ShowWindow(GetDlgItem(hDlg, IDOK), SW_HIDE);
|
|
ShowWindow(GetDlgItem(hDlg, IDCANCEL), SW_HIDE);
|
|
}
|
|
|
|
//
|
|
// Get in the correct context before we reference the registry
|
|
//
|
|
pGlobals = (PGLOBALS)GetWindowLong(hDlg, GWL_USERDATA);
|
|
|
|
if (OpenHKeyCurrentUser(pGlobals)) {
|
|
|
|
//
|
|
// Check the button which was the users last shutdown selection.
|
|
//
|
|
if (RegCreateKeyEx(HKEY_CURRENT_USER, SHUTDOWN_SETTING_KEY, 0, 0, 0,
|
|
KEY_READ | KEY_WRITE,
|
|
NULL, &hkeyShutdown, &dwDisposition) == ERROR_SUCCESS)
|
|
{
|
|
cbData = sizeof(dwShutdown);
|
|
RegQueryValueEx(hkeyShutdown, SHUTDOWN_SETTING, 0, &dwType, (LPBYTE)&dwShutdown, &cbData);
|
|
RegCloseKey(hkeyShutdown);
|
|
}
|
|
|
|
CloseHKeyCurrentUser(pGlobals);
|
|
|
|
} else {
|
|
DebugLog((DEB_ERROR, "ShutdownQueryDlgProc: Failed to open HKeyCurrentUser"));
|
|
dwShutdown = 0;
|
|
}
|
|
|
|
|
|
|
|
switch(dwShutdown)
|
|
{
|
|
case DLGSEL_SHUTDOWN_AND_RESTART:
|
|
CheckDlgButton(hDlg, IDD_RESTART, 1);
|
|
break;
|
|
case DLGSEL_SHUTDOWN_AND_POWEROFF:
|
|
if (bPowerdown)
|
|
{
|
|
CheckDlgButton(hDlg, IDD_POWEROFF, 1);
|
|
break;
|
|
}
|
|
//
|
|
// Fall thru,
|
|
// If poweroff is not enabled on the computer, just select shutdown.
|
|
//
|
|
default:
|
|
CheckDlgButton(hDlg, IDD_SHUTDOWN, 1);
|
|
break;
|
|
}
|
|
|
|
// 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:
|
|
case IDOK2:
|
|
nResult = MSGINA_DLG_SHUTDOWN_FLAG | MSGINA_DLG_SHUTDOWN;
|
|
if (IsDlgButtonChecked(hDlg, IDD_RESTART))
|
|
{
|
|
nResult |= MSGINA_DLG_REBOOT_FLAG;
|
|
dwShutdown = DLGSEL_SHUTDOWN_AND_RESTART;
|
|
}
|
|
else if (IsDlgButtonChecked(hDlg, IDD_POWEROFF))
|
|
{
|
|
nResult |= MSGINA_DLG_POWEROFF_FLAG;
|
|
dwShutdown = DLGSEL_SHUTDOWN_AND_POWEROFF;
|
|
}
|
|
else
|
|
{
|
|
dwShutdown = DLGSEL_SHUTDOWN;
|
|
}
|
|
|
|
//
|
|
// Get in the correct context before we reference the registry
|
|
//
|
|
pGlobals = (PGLOBALS)GetWindowLong(hDlg, GWL_USERDATA);
|
|
|
|
if (OpenHKeyCurrentUser(pGlobals)) {
|
|
|
|
if (RegCreateKeyEx(HKEY_CURRENT_USER, SHUTDOWN_SETTING_KEY, 0, 0, 0,
|
|
KEY_READ | KEY_WRITE,
|
|
NULL, &hkeyShutdown, &dwDisposition) == ERROR_SUCCESS)
|
|
{
|
|
cbData = sizeof(dwShutdown);
|
|
RegSetValueEx(hkeyShutdown, SHUTDOWN_SETTING, 0, REG_DWORD, (LPBYTE)&dwShutdown, sizeof(dwShutdown));
|
|
RegCloseKey(hkeyShutdown);
|
|
}
|
|
|
|
CloseHKeyCurrentUser(pGlobals);
|
|
|
|
} else {
|
|
DebugLog((DEB_ERROR, "ShutdownDlgQueryProc: Failed to open HKeyCurrentUser"));
|
|
}
|
|
|
|
|
|
EndDialog(hDlg, nResult);
|
|
return(TRUE);
|
|
|
|
case IDCANCEL:
|
|
case IDCANCEL2:
|
|
EndDialog(hDlg, MSGINA_DLG_FAILURE);
|
|
return(TRUE);
|
|
}
|
|
break;
|
|
}
|
|
|
|
// We didn't process the message
|
|
return(FALSE);
|
|
}
|
|
|
|
/***************************************************************************\
|
|
* 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.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
BOOL WINAPI
|
|
EndWindowsSessionDlgProc(
|
|
HWND hDlg,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
|
|
switch (message)
|
|
{
|
|
|
|
case WM_INITDIALOG:
|
|
SetWindowLong(hDlg, GWL_USERDATA, lParam);
|
|
|
|
// 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;
|
|
}
|
|
|
|
// We didn't process the message
|
|
return(FALSE);
|
|
}
|