[WIN32K:NTUSER] Get rid of the cached window station Name member, and instead just use the name stored in the NT Object's header.

CORE-11933 and PR #621.

- Remove the related hack-FIXMEs;
- Adjust NtUserGetObjectInformation() in accordance.
- Retrieve the window-station/desktop object type string in NtUserGetObjectInformation()
  also from the NT Object's header.

Also simplify the UOI_FLAGS case of NtUserGetObjectInformation() by reading
the handle inheritance information directly from the OBJECT_HANDLE_INFORMATION
structure returned by ObReferenceObjectByHandle().
This commit is contained in:
Hermès Bélusca-Maïto 2018-06-17 19:40:32 +02:00
parent dae57caa36
commit 43e2ab208a
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
3 changed files with 51 additions and 59 deletions

View file

@ -33,7 +33,8 @@ BOOL g_PaintDesktopVersion = FALSE;
} \ } \
else \ else \
{ \ { \
ERR("NtUserSystemParametersInfo requires interactive window station (current is %wZ)\n", &GetW32ProcessInfo()->prpwinsta->Name); \ ERR("NtUserSystemParametersInfo requires interactive window station (current is %wZ)\n", \
&(OBJECT_HEADER_TO_NAME_INFO(OBJECT_TO_OBJECT_HEADER(GetW32ProcessInfo()->prpwinsta))->Name)); \
} \ } \
EngSetLastError(err); \ EngSetLastError(err); \
return 0; \ return 0; \

View file

@ -114,8 +114,6 @@ IntWinStaObjectDelete(
RtlDestroyAtomTable(WinSta->AtomTable); RtlDestroyAtomTable(WinSta->AtomTable);
RtlFreeUnicodeString(&WinSta->Name);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -449,8 +447,6 @@ IntCreateWindowStation(
RtlZeroMemory(WindowStationObject, sizeof(WINSTATION_OBJECT)); RtlZeroMemory(WindowStationObject, sizeof(WINSTATION_OBJECT));
InitializeListHead(&WindowStationObject->DesktopListHead); InitializeListHead(&WindowStationObject->DesktopListHead);
WindowStationObject->Name = *ObjectAttributes->ObjectName;
ObjectAttributes->ObjectName = NULL; // FIXME! (see NtUserCreateWindowStation())
WindowStationObject->dwSessionId = NtCurrentPeb()->SessionId; WindowStationObject->dwSessionId = NtCurrentPeb()->SessionId;
Status = RtlCreateAtomTable(37, &WindowStationObject->AtomTable); Status = RtlCreateAtomTable(37, &WindowStationObject->AtomTable);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -491,7 +487,7 @@ IntCreateWindowStation(
} }
TRACE("IntCreateWindowStation created object 0x%p with name %wZ handle 0x%p\n", TRACE("IntCreateWindowStation created object 0x%p with name %wZ handle 0x%p\n",
WindowStationObject, &WindowStationObject->Name, WindowStation); WindowStationObject, ObjectAttributes->ObjectName, WindowStation);
*phWinSta = WindowStation; *phWinSta = WindowStation;
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -582,23 +578,7 @@ NtUserCreateWindowStation(
return NULL; return NULL;
} }
WindowStationName.Length = wcslen(ServiceWinStaName) * sizeof(WCHAR); RtlInitUnicodeString(&WindowStationName, ServiceWinStaName);
WindowStationName.MaximumLength =
WindowStationName.Length + sizeof(UNICODE_NULL);
WindowStationName.Buffer =
ExAllocatePoolWithTag(PagedPool,
WindowStationName.MaximumLength,
TAG_STRING);
if (!WindowStationName.Buffer)
{
Status = STATUS_NO_MEMORY;
ERR("Impossible to build a valid window station name, Status 0x%08lx\n", Status);
SetLastNtError(Status);
return NULL;
}
RtlStringCbCopyW(WindowStationName.Buffer,
WindowStationName.MaximumLength,
ServiceWinStaName);
LocalObjectAttributes.ObjectName = &WindowStationName; LocalObjectAttributes.ObjectName = &WindowStationName;
AccessMode = KernelMode; AccessMode = KernelMode;
} }
@ -615,12 +595,7 @@ NtUserCreateWindowStation(
Unknown5, Unknown5,
Unknown6); Unknown6);
// FIXME! Because in some situations we store the allocated window station name if ((AccessMode == UserMode) && LocalObjectAttributes.ObjectName)
// inside the window station, we must not free it now! We know this fact when
// IntCreateWindowStation() sets LocalObjectAttributes.ObjectName to NULL.
// This hack must be removed once we just use the stored Ob name instead
// (in which case we will always free the allocated name here).
if (LocalObjectAttributes.ObjectName)
ExFreePoolWithTag(LocalObjectAttributes.ObjectName->Buffer, TAG_STRING); ExFreePoolWithTag(LocalObjectAttributes.ObjectName->Buffer, TAG_STRING);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
@ -802,7 +777,11 @@ NtUserGetObjectInformation(
NTSTATUS Status; NTSTATUS Status;
PWINSTATION_OBJECT WinStaObject = NULL; PWINSTATION_OBJECT WinStaObject = NULL;
PDESKTOP DesktopObject = NULL; PDESKTOP DesktopObject = NULL;
POBJECT_HEADER ObjectHeader;
POBJECT_HEADER_NAME_INFO NameInfo;
OBJECT_HANDLE_INFORMATION HandleInfo;
USEROBJECTFLAGS ObjectFlags; USEROBJECTFLAGS ObjectFlags;
PUNICODE_STRING pStrNameU = NULL;
PVOID pvData = NULL; PVOID pvData = NULL;
SIZE_T nDataSize = 0; SIZE_T nDataSize = 0;
@ -820,13 +799,13 @@ NtUserGetObjectInformation(
_SEH2_END; _SEH2_END;
/* Try window station */ /* Try window station */
TRACE("Trying to open window station %p\n", hObject); TRACE("Trying to open window station 0x%p\n", hObject);
Status = ObReferenceObjectByHandle(hObject, Status = ObReferenceObjectByHandle(hObject,
0, 0,
ExWindowStationObjectType, ExWindowStationObjectType,
UserMode, UserMode,
(PVOID*)&WinStaObject, (PVOID*)&WinStaObject,
NULL); &HandleInfo);
if (Status == STATUS_OBJECT_TYPE_MISMATCH) if (Status == STATUS_OBJECT_TYPE_MISMATCH)
{ {
@ -852,23 +831,8 @@ NtUserGetObjectInformation(
{ {
case UOI_FLAGS: case UOI_FLAGS:
{ {
OBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleInfo;
ULONG BytesWritten;
ObjectFlags.fReserved = FALSE; ObjectFlags.fReserved = FALSE;
ObjectFlags.fInherit = !!(HandleInfo.HandleAttributes & OBJ_INHERIT);
/* Check whether this handle is inheritable */
Status = ZwQueryObject(hObject,
ObjectHandleFlagInformation,
&HandleInfo,
sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION),
&BytesWritten);
if (!NT_SUCCESS(Status))
{
ERR("ZwQueryObject failed, Status 0x%08lx\n", Status);
break;
}
ObjectFlags.fInherit = HandleInfo.Inherit;
ObjectFlags.dwFlags = 0; ObjectFlags.dwFlags = 0;
if (WinStaObject != NULL) if (WinStaObject != NULL)
@ -893,11 +857,24 @@ NtUserGetObjectInformation(
case UOI_NAME: case UOI_NAME:
{ {
// FIXME: Use either ObQueryNameString() or read directly that name inside the Object section!
if (WinStaObject != NULL) if (WinStaObject != NULL)
{ {
pvData = WinStaObject->Name.Buffer; ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
nDataSize = WinStaObject->Name.Length + sizeof(WCHAR); NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
if (NameInfo && (NameInfo->Name.Length > 0))
{
/* Named window station */
pStrNameU = &NameInfo->Name;
nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
}
else
{
/* Unnamed window station (should never happen!) */
ASSERT(FALSE);
pStrNameU = NULL;
nDataSize = sizeof(UNICODE_NULL);
}
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
} }
else if (DesktopObject != NULL) else if (DesktopObject != NULL)
@ -917,14 +894,16 @@ NtUserGetObjectInformation(
{ {
if (WinStaObject != NULL) if (WinStaObject != NULL)
{ {
pvData = L"WindowStation"; ObjectHeader = OBJECT_TO_OBJECT_HEADER(WinStaObject);
nDataSize = sizeof(L"WindowStation"); pStrNameU = &ObjectHeader->Type->Name;
nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
} }
else if (DesktopObject != NULL) else if (DesktopObject != NULL)
{ {
pvData = L"Desktop"; ObjectHeader = OBJECT_TO_OBJECT_HEADER(DesktopObject);
nDataSize = sizeof(L"Desktop"); pStrNameU = &ObjectHeader->Type->Name;
nDataSize = pStrNameU->Length + sizeof(UNICODE_NULL);
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
} }
else else
@ -954,11 +933,26 @@ Exit:
*nLengthNeeded = nDataSize; *nLengthNeeded = nDataSize;
/* Try to copy data to caller */ /* Try to copy data to caller */
if (Status == STATUS_SUCCESS) if (Status == STATUS_SUCCESS && (nDataSize > 0))
{ {
TRACE("Trying to copy data to caller (len = %lu, len needed = %lu)\n", nLength, nDataSize); TRACE("Trying to copy data to caller (len = %lu, len needed = %lu)\n", nLength, nDataSize);
if (pvData)
{
/* Copy the data */
RtlCopyMemory(pvInformation, pvData, nDataSize); RtlCopyMemory(pvInformation, pvData, nDataSize);
} }
else if (pStrNameU)
{
/* Copy and NULL-terminate the string */
RtlCopyMemory(pvInformation, pStrNameU->Buffer, pStrNameU->Length);
((PWCHAR)pvInformation)[pStrNameU->Length / sizeof(WCHAR)] = UNICODE_NULL;
}
else
{
/* Zero the memory */
RtlZeroMemory(pvInformation, nDataSize);
}
}
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {
@ -1026,8 +1020,6 @@ NtUserSetObjectInformation(
} }
HWINSTA FASTCALL HWINSTA FASTCALL
UserGetProcessWindowStation(VOID) UserGetProcessWindowStation(VOID)
{ {

View file

@ -15,7 +15,6 @@ typedef struct _WINSTATION_OBJECT
{ {
DWORD dwSessionId; DWORD dwSessionId;
UNICODE_STRING Name;
LIST_ENTRY DesktopListHead; LIST_ENTRY DesktopListHead;
PRTL_ATOM_TABLE AtomTable; PRTL_ATOM_TABLE AtomTable;
HANDLE ShellWindow; HANDLE ShellWindow;