[WINLOGON][USER32]

Fix the explanations of how Windows/ReactOS should shut down (it's winlogon itself that calls NtShutdownSystem, not something else; that story about "SMSS API #1" concerns the SMSS API SmpSessionCompleteApi called by the helper function SmSessionComplete which is in turn called by CSRSS function CsrDereferenceNtSession, when all win32 processes are gone, as it should).
The webpage http://www.reactos.org/wiki/ShutdownProcess should be corrected for.

[USER32]
Whitespace fixes for winstation code.

svn path=/trunk/; revision=66275
This commit is contained in:
Hermès Bélusca-Maïto 2015-02-15 02:07:23 +00:00
parent 61ec2f8e01
commit 4c28eeae21
3 changed files with 215 additions and 236 deletions

View file

@ -898,7 +898,8 @@ HandleShutdown(
/* Destroy SAS window */
UninitializeSAS(Session);
FIXME("FIXME: Call SMSS API #1\n");
/* Now we can shut down NT */
ERR("Shutting down NT...\n");
RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &Old);
if (wlxAction == WLX_SAS_ACTION_SHUTDOWN_REBOOT)
{

View file

@ -17,10 +17,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32);
*
* - App (usually explorer) calls ExitWindowsEx()
* - ExitWindowsEx() sends a message to CSRSS
* - CSRSS impersonates the caller and sends a message to a hidden WinLogon window
* - WinLogon checks if the caller has the required privileges
* - WinLogon enters pending log-out state
* - WinLogon impersonates the interactive user and calls ExitWindowsEx() again,
* - CSRSS impersonates the caller and sends a message to a hidden Winlogon window
* - Winlogon checks if the caller has the required privileges
* - Winlogon enters pending log-out state
* - Winlogon impersonates the interactive user and calls ExitWindowsEx() again,
* passing some special internal flags
* - CSRSS loops over all processes of the interactive user (sorted by their
* SetProcessShutdownParameters() level), sending WM_QUERYENDSESSION and
@ -39,28 +39,24 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32);
* If the handler doesn't respond in time the same activities as for GUI
* apps (i.e. display dialog box etc) take place. This also happens if
* the handler returns TRUE.
* - This ends the processing for the first ExitWindowsEx() call from WinLogon.
* Execution continues in WinLogon, which calls ExitWindowsEx() again to
* - This ends the processing for the first ExitWindowsEx() call from Winlogon.
* Execution continues in Winlogon, which calls ExitWindowsEx() again to
* terminate COM processes in the interactive user's session.
* - WinLogon stops impersonating the interactive user (whose processes are
* - Winlogon stops impersonating the interactive user (whose processes are
* all dead by now). and enters log-out state
* - If the ExitWindowsEx() request was for a logoff, WinLogon sends a SAS
* event (to display the "press ctrl+alt+del") to the GINA. WinLogon then
* - If the ExitWindowsEx() request was for a logoff, Winlogon sends a SAS
* event (to display the "press ctrl+alt+del") to the GINA. Winlogon then
* waits for the GINA to send a SAS event to login.
* - If the ExitWindowsEx() request was for shutdown/restart, WinLogon calls
* - If the ExitWindowsEx() request was for shutdown/restart, Winlogon calls
* ExitWindowsEx() again in the system process context.
* - CSRSS goes through the motions of sending WM_QUERYENDSESSION/WM_ENDSESSION
* to GUI processes running in the system process context but won't display
* dialog boxes or kill threads/processes. Same for console processes,
* using the CTRL_SHUTDOWN_EVENT. The Service Control Manager is one of
* these console processes and has a special timeout value WaitToKillServiceTimeout.
* - WinLogon issues a "InitiateSystemShutdown" request to the SM (SMSS API # 1)
* - the SM propagates the shutdown request to every environment subsystem it
* started since bootstrap time (still active ones, of course)
* - each environment subsystem, on shutdown request, releases every resource
* it aquired during its life (processes, memory etc), then dies
* - when every environment subsystem has gone to bed, the SM actually initiates
* the kernel and executive shutdown by calling NtShutdownSystem.
* - After CSRSS has finished its pass notifying processes that system is shutting down,
* Winlogon finishes the shutdown process by calling the executive subsystem
* function NtShutdownSystem.
*/
typedef struct

View file

@ -19,9 +19,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(winsta);
*/
HWINSTA WINAPI
CreateWindowStationA(LPCSTR lpwinsta,
DWORD dwReserved,
ACCESS_MASK dwDesiredAccess,
LPSECURITY_ATTRIBUTES lpsa)
DWORD dwReserved,
ACCESS_MASK dwDesiredAccess,
LPSECURITY_ATTRIBUTES lpsa)
{
UNICODE_STRING WindowStationNameU;
HWINSTA hWinSta;
@ -53,55 +53,55 @@ CreateWindowStationA(LPCSTR lpwinsta,
*/
HWINSTA WINAPI
CreateWindowStationW(LPCWSTR lpwinsta,
DWORD dwReserved,
ACCESS_MASK dwDesiredAccess,
LPSECURITY_ATTRIBUTES lpsa)
DWORD dwReserved,
ACCESS_MASK dwDesiredAccess,
LPSECURITY_ATTRIBUTES lpsa)
{
UNICODE_STRING WindowStationName;
UNICODE_STRING WindowStationsDir = RTL_CONSTANT_STRING(L"\\Windows\\WindowStations");
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hWindowStationsDir;
NTSTATUS Status;
HWINSTA hwinsta;
UNICODE_STRING WindowStationName;
UNICODE_STRING WindowStationsDir = RTL_CONSTANT_STRING(L"\\Windows\\WindowStations");
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hWindowStationsDir;
NTSTATUS Status;
HWINSTA hwinsta;
/* Open WindowStations directory */
InitializeObjectAttributes(&ObjectAttributes,
&WindowStationsDir,
OBJ_CASE_INSENSITIVE,
0,
0);
/* Open WindowStations directory */
InitializeObjectAttributes(&ObjectAttributes,
&WindowStationsDir,
OBJ_CASE_INSENSITIVE,
0,
0);
Status = NtOpenDirectoryObject(&hWindowStationsDir,
DIRECTORY_CREATE_OBJECT,
&ObjectAttributes);
if(!NT_SUCCESS(Status))
{
ERR("Failed to open WindowStations directory\n");
return NULL;
}
Status = NtOpenDirectoryObject(&hWindowStationsDir,
DIRECTORY_CREATE_OBJECT,
&ObjectAttributes);
if(!NT_SUCCESS(Status))
{
ERR("Failed to open WindowStations directory\n");
return NULL;
}
RtlInitUnicodeString(&WindowStationName, lpwinsta);
RtlInitUnicodeString(&WindowStationName, lpwinsta);
/* Create the window station object */
InitializeObjectAttributes(&ObjectAttributes,
&WindowStationName,
OBJ_CASE_INSENSITIVE,
hWindowStationsDir,
0);
/* Create the window station object */
InitializeObjectAttributes(&ObjectAttributes,
&WindowStationName,
OBJ_CASE_INSENSITIVE,
hWindowStationsDir,
0);
/* Check if the handle should be inheritable */
if (lpsa && lpsa->bInheritHandle)
{
ObjectAttributes.Attributes |= OBJ_INHERIT;
}
/* Check if the handle should be inheritable */
if (lpsa && lpsa->bInheritHandle)
{
ObjectAttributes.Attributes |= OBJ_INHERIT;
}
hwinsta = NtUserCreateWindowStation(&ObjectAttributes,
dwDesiredAccess,
0, 0, 0, 0, 0);
hwinsta = NtUserCreateWindowStation(&ObjectAttributes,
dwDesiredAccess,
0, 0, 0, 0, 0);
NtClose(hWindowStationsDir);
NtClose(hWindowStationsDir);
return hwinsta;
return hwinsta;
}
/*
@ -110,87 +110,78 @@ CreateWindowStationW(LPCWSTR lpwinsta,
BOOL FASTCALL
EnumNamesW(HWINSTA WindowStation,
NAMEENUMPROCW EnumFunc,
LPARAM Context,
LPARAM Context,
BOOL Desktops)
{
char Buffer[256];
PVOID NameList;
PWCHAR Name;
NTSTATUS Status;
ULONG RequiredSize;
ULONG CurrentEntry, EntryCount;
BOOL Ret;
CHAR Buffer[256];
PVOID NameList;
PWCHAR Name;
NTSTATUS Status;
ULONG RequiredSize;
ULONG CurrentEntry, EntryCount;
BOOL Ret;
/*
* Check parameters
*/
if (NULL == WindowStation && Desktops)
{
WindowStation = GetProcessWindowStation();
}
/* Check parameters */
if (WindowStation == NULL && Desktops)
{
WindowStation = GetProcessWindowStation();
}
/*
* Try with fixed-size buffer
*/
Status = NtUserBuildNameList(WindowStation, sizeof(Buffer), Buffer, &RequiredSize);
if (NT_SUCCESS(Status))
{
/* Fixed-size buffer is large enough */
NameList = (PWCHAR) Buffer;
}
else if (Status == STATUS_BUFFER_TOO_SMALL)
{
/* Allocate a larger buffer */
NameList = HeapAlloc(GetProcessHeap(), 0, RequiredSize);
if (NULL == NameList)
{
return FALSE;
}
/* Try again */
Status = NtUserBuildNameList(WindowStation, RequiredSize, NameList, NULL);
if (! NT_SUCCESS(Status))
{
HeapFree(GetProcessHeap(), 0, NameList);
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
}
else
{
/* Some unrecognized error occured */
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
/* Try with fixed-size buffer */
Status = NtUserBuildNameList(WindowStation, sizeof(Buffer), Buffer, &RequiredSize);
if (NT_SUCCESS(Status))
{
/* Fixed-size buffer is large enough */
NameList = (PWCHAR) Buffer;
}
else if (Status == STATUS_BUFFER_TOO_SMALL)
{
/* Allocate a larger buffer */
NameList = HeapAlloc(GetProcessHeap(), 0, RequiredSize);
if (NameList == NULL)
return FALSE;
/*
* Enum the names one by one
*/
EntryCount = *((DWORD *) NameList);
Name = (PWCHAR) ((PCHAR) NameList + sizeof(DWORD));
Ret = TRUE;
for (CurrentEntry = 0; CurrentEntry < EntryCount && Ret; ++CurrentEntry)
{
Ret = (*EnumFunc)(Name, Context);
Name += wcslen(Name) + 1;
}
/* Try again */
Status = NtUserBuildNameList(WindowStation, RequiredSize, NameList, NULL);
if (!NT_SUCCESS(Status))
{
HeapFree(GetProcessHeap(), 0, NameList);
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
}
else
{
/* Some unrecognized error occured */
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
/*
* Cleanup
*/
if (NameList != Buffer)
{
HeapFree(GetProcessHeap(), 0, NameList);
}
/* Enum the names one by one */
EntryCount = *((DWORD *) NameList);
Name = (PWCHAR) ((PCHAR) NameList + sizeof(DWORD));
Ret = TRUE;
for (CurrentEntry = 0; CurrentEntry < EntryCount && Ret; ++CurrentEntry)
{
Ret = (*EnumFunc)(Name, Context);
Name += wcslen(Name) + 1;
}
return Ret;
/* Cleanup */
if (NameList != Buffer)
{
HeapFree(GetProcessHeap(), 0, NameList);
}
return Ret;
}
/* For W->A conversion */
typedef struct tagENUMNAMESASCIICONTEXT
{
NAMEENUMPROCA UserEnumFunc;
LPARAM UserContext;
NAMEENUMPROCA UserEnumFunc;
LPARAM UserContext;
} ENUMNAMESASCIICONTEXT, *PENUMNAMESASCIICONTEXT;
/*
@ -200,65 +191,59 @@ typedef struct tagENUMNAMESASCIICONTEXT
BOOL CALLBACK
EnumNamesCallback(LPWSTR Name, LPARAM Param)
{
PENUMNAMESASCIICONTEXT Context = (PENUMNAMESASCIICONTEXT) Param;
char FixedNameA[32];
LPSTR NameA;
int Len;
BOOL Ret;
PENUMNAMESASCIICONTEXT Context = (PENUMNAMESASCIICONTEXT) Param;
CHAR FixedNameA[32];
LPSTR NameA;
INT Len;
BOOL Ret;
/*
* Determine required size of Ascii string and see if we can use
* fixed buffer
*/
Len = WideCharToMultiByte(CP_ACP, 0, Name, -1, NULL, 0, NULL, NULL);
if (Len <= 0)
{
/* Some strange error occured */
return FALSE;
}
else if (Len <= sizeof(FixedNameA))
{
/* Fixed-size buffer is large enough */
NameA = FixedNameA;
}
else
{
/* Allocate a larger buffer */
NameA = HeapAlloc(GetProcessHeap(), 0, Len);
if (NULL == NameA)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
}
/*
* Determine required size of Ascii string and see
* if we can use fixed buffer.
*/
Len = WideCharToMultiByte(CP_ACP, 0, Name, -1, NULL, 0, NULL, NULL);
if (Len <= 0)
{
/* Some strange error occured */
return FALSE;
}
else if (Len <= sizeof(FixedNameA))
{
/* Fixed-size buffer is large enough */
NameA = FixedNameA;
}
else
{
/* Allocate a larger buffer */
NameA = HeapAlloc(GetProcessHeap(), 0, Len);
if (NULL == NameA)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
}
/*
* Do the Unicode ->Ascii conversion
*/
if (0 == WideCharToMultiByte(CP_ACP, 0, Name, -1, NameA, Len, NULL, NULL))
{
/* Something went wrong, clean up */
if (NameA != FixedNameA)
{
HeapFree(GetProcessHeap(), 0, NameA);
}
return FALSE;
}
/* Do the Unicode ->Ascii conversion */
if (0 == WideCharToMultiByte(CP_ACP, 0, Name, -1, NameA, Len, NULL, NULL))
{
/* Something went wrong, clean up */
if (NameA != FixedNameA)
{
HeapFree(GetProcessHeap(), 0, NameA);
}
return FALSE;
}
/*
* Call user callback
*/
Ret = Context->UserEnumFunc(NameA, Context->UserContext);
/* Call user callback */
Ret = Context->UserEnumFunc(NameA, Context->UserContext);
/*
* Clean up
*/
if (NameA != FixedNameA)
{
HeapFree(GetProcessHeap(), 0, NameA);
}
/* Cleanup */
if (NameA != FixedNameA)
{
HeapFree(GetProcessHeap(), 0, NameA);
}
return Ret;
return Ret;
}
/*
@ -267,15 +252,15 @@ EnumNamesCallback(LPWSTR Name, LPARAM Param)
BOOL FASTCALL
EnumNamesA(HWINSTA WindowStation,
NAMEENUMPROCA EnumFunc,
LPARAM Context,
LPARAM Context,
BOOL Desktops)
{
ENUMNAMESASCIICONTEXT PrivateContext;
ENUMNAMESASCIICONTEXT PrivateContext;
PrivateContext.UserEnumFunc = EnumFunc;
PrivateContext.UserContext = Context;
PrivateContext.UserEnumFunc = EnumFunc;
PrivateContext.UserContext = Context;
return EnumNamesW(WindowStation, EnumNamesCallback, (LPARAM) &PrivateContext, Desktops);
return EnumNamesW(WindowStation, EnumNamesCallback, (LPARAM) &PrivateContext, Desktops);
}
/*
@ -283,9 +268,9 @@ EnumNamesA(HWINSTA WindowStation,
*/
BOOL WINAPI
EnumWindowStationsA(WINSTAENUMPROCA EnumFunc,
LPARAM Context)
LPARAM Context)
{
return EnumNamesA(NULL, EnumFunc, Context, FALSE);
return EnumNamesA(NULL, EnumFunc, Context, FALSE);
}
@ -294,9 +279,9 @@ EnumWindowStationsA(WINSTAENUMPROCA EnumFunc,
*/
BOOL WINAPI
EnumWindowStationsW(WINSTAENUMPROCW EnumFunc,
LPARAM Context)
LPARAM Context)
{
return EnumNamesW(NULL, EnumFunc, Context, FALSE);
return EnumNamesW(NULL, EnumFunc, Context, FALSE);
}
@ -305,8 +290,8 @@ EnumWindowStationsW(WINSTAENUMPROCW EnumFunc,
*/
HWINSTA WINAPI
OpenWindowStationA(LPCSTR lpszWinSta,
BOOL fInherit,
ACCESS_MASK dwDesiredAccess)
BOOL fInherit,
ACCESS_MASK dwDesiredAccess)
{
UNICODE_STRING WindowStationNameU;
HWINSTA hWinSta;
@ -340,48 +325,48 @@ OpenWindowStationW(LPCWSTR lpszWinSta,
BOOL fInherit,
ACCESS_MASK dwDesiredAccess)
{
UNICODE_STRING WindowStationName;
UNICODE_STRING WindowStationsDir = RTL_CONSTANT_STRING(L"\\Windows\\WindowStations");
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hWindowStationsDir;
NTSTATUS Status;
HWINSTA hwinsta;
UNICODE_STRING WindowStationName;
UNICODE_STRING WindowStationsDir = RTL_CONSTANT_STRING(L"\\Windows\\WindowStations");
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE hWindowStationsDir;
NTSTATUS Status;
HWINSTA hwinsta;
/* Open WindowStations directory */
InitializeObjectAttributes(&ObjectAttributes,
&WindowStationsDir,
OBJ_CASE_INSENSITIVE,
0,
0);
/* Open WindowStations directory */
InitializeObjectAttributes(&ObjectAttributes,
&WindowStationsDir,
OBJ_CASE_INSENSITIVE,
0,
0);
Status = NtOpenDirectoryObject(&hWindowStationsDir,
DIRECTORY_TRAVERSE,
&ObjectAttributes);
if(!NT_SUCCESS(Status))
{
ERR("Failed to open WindowStations directory\n");
return NULL;
}
Status = NtOpenDirectoryObject(&hWindowStationsDir,
DIRECTORY_TRAVERSE,
&ObjectAttributes);
if(!NT_SUCCESS(Status))
{
ERR("Failed to open WindowStations directory\n");
return NULL;
}
/* Open the window station object */
RtlInitUnicodeString(&WindowStationName, lpszWinSta);
/* Open the window station object */
RtlInitUnicodeString(&WindowStationName, lpszWinSta);
InitializeObjectAttributes(&ObjectAttributes,
&WindowStationName,
OBJ_CASE_INSENSITIVE,
hWindowStationsDir,
0);
InitializeObjectAttributes(&ObjectAttributes,
&WindowStationName,
OBJ_CASE_INSENSITIVE,
hWindowStationsDir,
0);
if( fInherit )
{
ObjectAttributes.Attributes |= OBJ_INHERIT;
}
if(fInherit)
{
ObjectAttributes.Attributes |= OBJ_INHERIT;
}
hwinsta = NtUserOpenWindowStation(&ObjectAttributes, dwDesiredAccess);
hwinsta = NtUserOpenWindowStation(&ObjectAttributes, dwDesiredAccess);
NtClose(hWindowStationsDir);
NtClose(hWindowStationsDir);
return hwinsta;
return hwinsta;
}
@ -390,15 +375,12 @@ OpenWindowStationW(LPCWSTR lpszWinSta,
*/
BOOL
WINAPI
SetWindowStationUser(
HWINSTA hWindowStation,
PLUID pluid,
PSID psid,
DWORD size
)
SetWindowStationUser(HWINSTA hWindowStation,
PLUID pluid,
PSID psid,
DWORD size)
{
return NtUserSetWindowStationUser(hWindowStation, pluid, psid, size);
return NtUserSetWindowStationUser(hWindowStation, pluid, psid, size);
}
/* EOF */