- Part 2/2 of SrvLogon (see r66303): load the per-user shutdown timeouts.
- Retrieve those per-user shutdown timeouts from the registry when the user logs on, adapted from Alex' shutdown patch plus existing code.
- Commit the main part of shutdown code (finally!), still unfinished yet:
  * Need to switch to the desktop where the hanging GUI app's window is present,
  * Need to deal with apps from other users
  * What about SYSTEM processes?
  * What about console processes?
- Reuse the old timeout code.
- Fix the sending of WM_QUERYENDSESSION and WM_ENDSESSION messages (this is done by win32k directly; for that winsrv needs just to send one WM_CLIENTSHUTDOWN message with the correct wParam parameter).

Part 13/X
CORE-8322 #comment Big commit in revision 66306!

svn path=/trunk/; revision=66306
This commit is contained in:
Hermès Bélusca-Maïto 2015-02-15 22:57:40 +00:00
parent c7457ca21e
commit 9d4dbeb5c9
5 changed files with 502 additions and 446 deletions

View file

@ -18,7 +18,6 @@
#define COM_NO_WINDOWS_H
#include <winnls.h>
#include <winreg.h>
#include <wincon.h>
#define NTOS_MODE_USER

View file

@ -14,6 +14,157 @@
#define NDEBUG
#include <debug.h>
/* GLOBALS ********************************************************************/
#define DEFAULT_AUTO_END_TASKS FALSE
#define DEFAULT_HUNG_APP_TIMEOUT 5000
#define DEFAULT_WAIT_TO_KILL_APP_TIMEOUT 20000
#define DEFAULT_PROCESS_TERMINATE_TIMEOUT 90000
SHUTDOWN_SETTINGS ShutdownSettings =
{
DEFAULT_AUTO_END_TASKS,
DEFAULT_HUNG_APP_TIMEOUT,
DEFAULT_WAIT_TO_KILL_APP_TIMEOUT,
DEFAULT_WAIT_TO_KILL_APP_TIMEOUT,
DEFAULT_PROCESS_TERMINATE_TIMEOUT
};
/* FUNCTIONS ******************************************************************/
static ULONG
GetRegIntFromID(IN HANDLE KeyHandle,
IN PWCHAR ValueName,
IN ULONG DefaultValue)
{
UNICODE_STRING ValueString;
ULONG Length;
UCHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 32 * sizeof(WCHAR)];
PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PVOID)Buffer;
NTSTATUS Status;
ULONG Value;
/* Open the key */
RtlInitUnicodeString(&ValueString, ValueName);
Status = NtQueryValueKey(KeyHandle,
&ValueString,
KeyValuePartialInformation,
PartialInfo,
sizeof(Buffer),
&Length);
if (NT_SUCCESS(Status))
{
if (PartialInfo->Type == REG_SZ)
{
/* Convert to integer */
RtlInitUnicodeString(&ValueString, (PWCHAR)PartialInfo->Data);
Status = RtlUnicodeStringToInteger(&ValueString, 10, &Value);
}
else if (PartialInfo->Type == REG_DWORD)
{
/* Directly retrieve the data */
Value = *(PULONG)PartialInfo->Data;
Status = STATUS_SUCCESS;
}
else
{
DPRINT1("Unexpected registry type %d for setting %S\n", PartialInfo->Type, ValueName);
Status = STATUS_UNSUCCESSFUL;
}
}
if (!NT_SUCCESS(Status))
{
/* Use default value instead */
Value = DefaultValue;
}
/* Return the value */
return Value;
}
VOID FASTCALL
GetTimeouts(IN PSHUTDOWN_SETTINGS ShutdownSettings)
{
NTSTATUS Status;
UNICODE_STRING RegistryString;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE CurrentUserKeyHandle;
HANDLE KeyHandle;
/* Initialize with defaults first */
ShutdownSettings->AutoEndTasks = DEFAULT_AUTO_END_TASKS;
ShutdownSettings->HungAppTimeout = DEFAULT_HUNG_APP_TIMEOUT;
ShutdownSettings->WaitToKillAppTimeout = DEFAULT_WAIT_TO_KILL_APP_TIMEOUT;
ShutdownSettings->WaitToKillServiceTimeout = ShutdownSettings->WaitToKillAppTimeout;
ShutdownSettings->ProcessTerminateTimeout = DEFAULT_PROCESS_TERMINATE_TIMEOUT;
/* Open the per-user desktop key */
Status = RtlOpenCurrentUser(MAXIMUM_ALLOWED, &CurrentUserKeyHandle);
if (NT_SUCCESS(Status))
{
RtlInitUnicodeString(&RegistryString,
L"Control Panel\\Desktop");
InitializeObjectAttributes(&ObjectAttributes,
&RegistryString,
OBJ_CASE_INSENSITIVE,
CurrentUserKeyHandle,
NULL);
Status = NtOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
if (NT_SUCCESS(Status))
{
/* Read timeouts */
ShutdownSettings->HungAppTimeout = GetRegIntFromID(KeyHandle,
L"HungAppTimeout",
DEFAULT_HUNG_APP_TIMEOUT);
ShutdownSettings->WaitToKillAppTimeout = GetRegIntFromID(KeyHandle,
L"WaitToKillAppTimeout",
DEFAULT_WAIT_TO_KILL_APP_TIMEOUT);
ShutdownSettings->AutoEndTasks = GetRegIntFromID(KeyHandle,
L"AutoEndTasks",
DEFAULT_AUTO_END_TASKS);
/* Done */
NtClose(KeyHandle);
}
/* Done */
NtClose(CurrentUserKeyHandle);
}
/* Now open the control key */
RtlInitUnicodeString(&RegistryString,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
InitializeObjectAttributes(&ObjectAttributes,
&RegistryString,
OBJ_CASE_INSENSITIVE,
NULL, NULL);
Status = NtOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes);
if (NT_SUCCESS(Status))
{
/* Read the services timeout */
ShutdownSettings->WaitToKillServiceTimeout = GetRegIntFromID(KeyHandle,
L"WaitToKillServiceTimeout",
ShutdownSettings->WaitToKillAppTimeout);
/*
* Retrieve the process terminate timeout.
* See ftp://ftp.microsoft.com/MISC1/BUSSYS/WINNT/KB/Q234/6/06.TXT
* and https://web.archive.org/web/20050216235758/http://support.microsoft.com/kb/234606/EN-US/
* for more details.
*
* NOTE: Unused at the moment...
*/
ShutdownSettings->ProcessTerminateTimeout = GetRegIntFromID(KeyHandle,
L"ProcessTerminateTimeout",
DEFAULT_PROCESS_TERMINATE_TIMEOUT);
if (ShutdownSettings->ProcessTerminateTimeout < DEFAULT_HUNG_APP_TIMEOUT)
ShutdownSettings->ProcessTerminateTimeout = DEFAULT_HUNG_APP_TIMEOUT;
/* Done */
NtClose(KeyHandle);
}
}
/* ENTRY-POINT ****************************************************************/
BOOL

View file

@ -137,6 +137,23 @@ CSR_API(SrvDeviceEvent)
return STATUS_NOT_IMPLEMENTED;
}
CSR_API(SrvLogon)
{
PUSER_LOGON LogonRequest = &((PUSER_API_MESSAGE)ApiMessage)->Data.LogonRequest;
DPRINT1("We are logged %s\n", LogonRequest->IsLogon ? "on" : "off");
/* Impersonate the caller in order to retrieve settings in its context */
if (!CsrImpersonateClient(NULL))
return STATUS_UNSUCCESSFUL;
GetTimeouts(&ShutdownSettings);
/* We are done */
CsrRevertToSelf();
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
UserClientConnect(IN PCSR_PROCESS CsrProcess,

File diff suppressed because it is too large Load diff

View file

@ -20,6 +20,7 @@
#include <windef.h>
#include <winbase.h>
#include <wingdi.h>
#include <winreg.h>
#include <winuser.h>
#include <imm.h>
@ -42,4 +43,18 @@
/* CSRSS Header */
#include <csr/csrsrv.h>
typedef struct tagSHUTDOWN_SETTINGS
{
BOOL AutoEndTasks;
ULONG HungAppTimeout;
ULONG WaitToKillAppTimeout;
ULONG WaitToKillServiceTimeout;
ULONG ProcessTerminateTimeout;
} SHUTDOWN_SETTINGS, *PSHUTDOWN_SETTINGS;
extern SHUTDOWN_SETTINGS ShutdownSettings;
VOID FASTCALL
GetTimeouts(IN PSHUTDOWN_SETTINGS ShutdownSettings);
#endif /* __WINSRV_H__ */