/* INITIALIZATION FUNCTIONS ****************************************************/
-INIT_FUNCTION
+CODE_SEG("INIT")
NTSTATUS
NTAPI
InitWindowStationImpl(VOID)
RtlDestroyAtomTable(WinSta->AtomTable);
+ UserAssignmentUnlock((PVOID*)&WinSta->spklList);
+
return STATUS_SUCCESS;
}
UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY");
PDESKTOP pdesk;
+ if (PDEVOBJ_lChangeDisplaySettings(NULL, NULL, NULL, &gpmdev, TRUE) != DISP_CHANGE_SUCCESSFUL)
+ {
+ ERR("PDEVOBJ_lChangeDisplaySettings() failed.\n");
+ return FALSE;
+ }
+
ScreenDeviceContext = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE);
if (NULL == ScreenDeviceContext)
{
}
GreSetDCOwner(ScreenDeviceContext, GDI_OBJ_HMGR_PUBLIC);
- if (! IntCreatePrimarySurface())
+ if (!IntCreatePrimarySurface())
{
return FALSE;
}
NtGdiSelectFont(hSystemBM, NtGdiGetStockObject(SYSTEM_FONT));
GreSetDCOwner(hSystemBM, GDI_OBJ_HMGR_PUBLIC);
+ /* Update the system metrics */
+ InitMetrics();
+
+ /* Set new size of the monitor */
+ UserUpdateMonitorSize((HDEV)gpmdev->ppdevGlobal);
+
/* Update the SERVERINFO */
- gpsi->aiSysMet[SM_CXSCREEN] = gppdevPrimary->gdiinfo.ulHorzRes;
- gpsi->aiSysMet[SM_CYSCREEN] = gppdevPrimary->gdiinfo.ulVertRes;
+ gpsi->aiSysMet[SM_CXSCREEN] = gpmdev->ppdevGlobal->gdiinfo.ulHorzRes;
+ gpsi->aiSysMet[SM_CYSCREEN] = gpmdev->ppdevGlobal->gdiinfo.ulVertRes;
gpsi->Planes = NtGdiGetDeviceCaps(ScreenDeviceContext, PLANES);
gpsi->BitsPixel = NtGdiGetDeviceCaps(ScreenDeviceContext, BITSPIXEL);
gpsi->BitCount = gpsi->Planes * gpsi->BitsPixel;
gpsi->PUSIFlags |= PUSIF_PALETTEDISPLAY;
}
else
+ {
gpsi->PUSIFlags &= ~PUSIF_PALETTEDISPLAY;
+ }
// Font is realized and this dc was previously set to internal DC_ATTR.
gpsi->cxSysFontChar = IntGetCharDimensions(hSystemBM, &tmw, (DWORD*)&gpsi->cySysFontChar);
gpsi->tmSysFont = tmw;
gpsi->ptCursor.y = gpsi->aiSysMet[SM_CYSCREEN] / 2;
/* Attach monitor */
- UserAttachMonitor((HDEV)gppdevPrimary);
+ UserAttachMonitor((HDEV)gpmdev->ppdevGlobal);
/* Setup the cursor */
co_IntLoadDefaultCursors();
ASSERT(pdesk);
co_IntShowDesktop(pdesk, gpsi->aiSysMet[SM_CXSCREEN], gpsi->aiSysMet[SM_CYSCREEN], TRUE);
+ /* HACK: display wallpaper on all secondary displays */
+ {
+ PGRAPHICS_DEVICE pGraphicsDevice;
+ UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"DISPLAY");
+ UNICODE_STRING DisplayName;
+ HDC hdc;
+ ULONG iDevNum;
+
+ for (iDevNum = 1; (pGraphicsDevice = EngpFindGraphicsDevice(NULL, iDevNum)) != NULL; iDevNum++)
+ {
+ RtlInitUnicodeString(&DisplayName, pGraphicsDevice->szWinDeviceName);
+ hdc = IntGdiCreateDC(&DriverName, &DisplayName, NULL, NULL, FALSE);
+ IntPaintDesktop(hdc);
+ }
+ }
+
return TRUE;
}
InputWindowStation = WindowStation;
WindowStation->Flags &= ~WSS_NOIO;
+
InitCursorImpl();
+
+ UserCreateSystemThread(ST_DESKTOP_THREAD);
+ UserCreateSystemThread(ST_RIT);
+
+ /* Desktop functions require the desktop thread running so wait for it to initialize */
+ UserLeaveCo();
+ KeWaitForSingleObject(gpDesktopThreadStartedEvent,
+ UserRequest,
+ UserMode,
+ FALSE,
+ NULL);
+ UserEnterCo();
}
else
{
ObjectAttributes->ObjectName, WindowStation, hWinSta);
*phWinSta = hWinSta;
+ EngSetLastError(ERROR_SUCCESS);
+
return STATUS_SUCCESS;
}
return NULL;
}
+ UserEnterExclusive();
+
/* Create the window station */
Status = IntCreateWindowStation(&hWinSta,
ObjectAttributes,
Unknown4,
Unknown5,
Unknown6);
+ UserLeave();
+
if (NT_SUCCESS(Status))
{
TRACE("NtUserCreateWindowStation created window station '%wZ' with handle 0x%p\n",
0,
&Object,
NULL);
-
if (!NT_SUCCESS(Status))
{
ERR("Validation of window station handle (%p) failed\n", hWinSta);
BOOL FASTCALL
UserSetProcessWindowStation(HWINSTA hWindowStation)
{
- PPROCESSINFO ppi;
NTSTATUS Status;
- HWINSTA hwinstaOld;
+ PPROCESSINFO ppi;
OBJECT_HANDLE_INFORMATION ObjectHandleInfo;
PWINSTATION_OBJECT NewWinSta = NULL, OldWinSta;
+ HWINSTA hCacheWinSta;
ppi = PsGetCurrentProcessWin32Process();
&ObjectHandleInfo);
if (!NT_SUCCESS(Status))
{
- TRACE("Validation of window station handle (%p) failed\n",
- hWindowStation);
+ TRACE("Validation of window station handle 0x%p failed\n", hWindowStation);
SetLastNtError(Status);
return FALSE;
}
}
OldWinSta = ppi->prpwinsta;
- hwinstaOld = PsGetProcessWin32WindowStation(ppi->peProcess);
+ hCacheWinSta = PsGetProcessWin32WindowStation(ppi->peProcess);
/* Dereference the previous window station */
if (OldWinSta != NULL)
ObDereferenceObject(OldWinSta);
}
- /* Check if we have a stale handle (it should happen for console apps) */
- if (hwinstaOld != ppi->hwinsta)
- {
- ObCloseHandle(hwinstaOld, UserMode);
- }
-
/*
- * FIXME: Don't allow changing the window station if there are threads that are attached to desktops and own GUI objects.
+ * FIXME: Don't allow changing the window station if there are threads that are attached to desktops and own GUI objects?
*/
- PsSetProcessWindowStation(ppi->peProcess, hWindowStation);
+ /* Close the cached EPROCESS window station handle if needed */
+ if (hCacheWinSta != NULL)
+ {
+ /* Reference the window station */
+ Status = ObReferenceObjectByHandle(hCacheWinSta,
+ 0,
+ ExWindowStationObjectType,
+ UserMode,
+ (PVOID*)&OldWinSta,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("Failed to reference the inherited window station, Status 0x%08lx\n", Status);
+ /* We failed, reset the cache */
+ hCacheWinSta = NULL;
+ PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
+ }
+ else
+ {
+ /*
+ * Close the old handle and reset the cache only
+ * if we are setting a different window station.
+ */
+ if (NewWinSta != OldWinSta)
+ {
+ ObCloseHandle(hCacheWinSta, UserMode);
+ hCacheWinSta = NULL;
+ PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
+ }
+
+ /* Dereference the window station */
+ ObDereferenceObject(OldWinSta);
+ }
+ }
+
+ /* Duplicate and save a new cached EPROCESS window station handle */
+ if ((hCacheWinSta == NULL) && (hWindowStation != NULL))
+ {
+ Status = ZwDuplicateObject(ZwCurrentProcess(),
+ hWindowStation,
+ ZwCurrentProcess(),
+ (PHANDLE)&hCacheWinSta,
+ 0,
+ 0,
+ DUPLICATE_SAME_ACCESS);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("UserSetProcessWindowStation: Failed to duplicate the window station handle, Status 0x%08lx\n", Status);
+ }
+ else
+ {
+ PsSetProcessWindowStation(ppi->peProcess, hCacheWinSta);
+ }
+ }
ppi->prpwinsta = NewWinSta;
ppi->hwinsta = hWindowStation;
{
ppi->W32PF_flags |= W32PF_IOWINSTA;
}
- else // Might be closed if the handle is null.
+ else /* Might be closed if the handle is NULL */
{
ppi->W32PF_flags &= ~W32PF_IOWINSTA;
}