mirror of
https://github.com/reactos/reactos.git
synced 2024-10-04 08:25:53 +00:00
[WINSRV]
- 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:
parent
c7457ca21e
commit
9d4dbeb5c9
|
@ -18,7 +18,6 @@
|
|||
#define COM_NO_WINDOWS_H
|
||||
|
||||
#include <winnls.h>
|
||||
#include <winreg.h>
|
||||
#include <wincon.h>
|
||||
|
||||
#define NTOS_MODE_USER
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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__ */
|
||||
|
|
Loading…
Reference in a new issue