/* GLOBALS *******************************************************************/
-/* These can be changed via csrss startup, these are defaults */
+/* These can be changed via CSRSS startup, these are defaults */
DWORD gdwDesktopSectionSize = 512;
DWORD gdwNOIOSectionSize = 128; // A guess, for one or more of the first three system desktops.
IntGetDesktopObjectHandle(PDESKTOP DesktopObject)
{
NTSTATUS Status;
- HDESK Ret;
+ HDESK hDesk;
ASSERT(DesktopObject);
DesktopObject,
ExDesktopObjectType,
NULL,
- (PHANDLE)&Ret))
+ (PHANDLE)&hDesk))
{
Status = ObOpenObjectByPointer(DesktopObject,
0,
0,
ExDesktopObjectType,
UserMode,
- (PHANDLE)&Ret);
+ (PHANDLE)&hDesk);
if (!NT_SUCCESS(Status))
{
/* Unable to create a handle */
}
else
{
- TRACE("Got handle: %p\n", Ret);
+ TRACE("Got handle: 0x%p\n", hDesk);
}
- return Ret;
+ return hDesk;
}
PUSER_MESSAGE_QUEUE FASTCALL
{
SIZE sz;
int x, y;
+ int scaledWidth, scaledHeight;
+ int wallpaperX, wallpaperY, wallpaperWidth, wallpaperHeight;
HDC hWallpaperDC;
sz.cx = WndDesktop->rcWindow.right - WndDesktop->rcWindow.left;
sz.cy = WndDesktop->rcWindow.bottom - WndDesktop->rcWindow.top;
+ if (gspv.WallpaperMode == wmFit ||
+ gspv.WallpaperMode == wmFill)
+ {
+ int scaleNum, scaleDen;
+
+ // Precision improvement over ((sz.cx / gspv.cxWallpaper) > (sz.cy / gspv.cyWallpaper))
+ if ((sz.cx * gspv.cyWallpaper) > (sz.cy * gspv.cxWallpaper))
+ {
+ if (gspv.WallpaperMode == wmFit)
+ {
+ scaleNum = sz.cy;
+ scaleDen = gspv.cyWallpaper;
+ }
+ else
+ {
+ scaleNum = sz.cx;
+ scaleDen = gspv.cxWallpaper;
+ }
+ }
+ else
+ {
+ if (gspv.WallpaperMode == wmFit)
+ {
+ scaleNum = sz.cx;
+ scaleDen = gspv.cxWallpaper;
+ }
+ else
+ {
+ scaleNum = sz.cy;
+ scaleDen = gspv.cyWallpaper;
+ }
+ }
+
+ scaledWidth = EngMulDiv(gspv.cxWallpaper, scaleNum, scaleDen);
+ scaledHeight = EngMulDiv(gspv.cyWallpaper, scaleNum, scaleDen);
+
+ if (gspv.WallpaperMode == wmFill)
+ {
+ wallpaperX = (((scaledWidth - sz.cx) * gspv.cxWallpaper) / (2 * scaledWidth));
+ wallpaperY = (((scaledHeight - sz.cy) * gspv.cyWallpaper) / (2 * scaledHeight));
+
+ wallpaperWidth = (sz.cx * gspv.cxWallpaper) / scaledWidth;
+ wallpaperHeight = (sz.cy * gspv.cyWallpaper) / scaledHeight;
+ }
+ }
+
if (gspv.WallpaperMode == wmStretch ||
- gspv.WallpaperMode == wmTile)
+ gspv.WallpaperMode == wmTile ||
+ gspv.WallpaperMode == wmFill)
{
x = 0;
y = 0;
}
+ else if (gspv.WallpaperMode == wmFit)
+ {
+ x = (sz.cx - scaledWidth) / 2;
+ y = (sz.cy - scaledHeight) / 2;
+ }
else
{
/* Find the upper left corner, can be negative if the bitmap is bigger than the screen */
}
}
}
+ else if (gspv.WallpaperMode == wmFit)
+ {
+ if (Rect.right && Rect.bottom)
+ {
+ NtGdiStretchBlt(hDC,
+ x,
+ y,
+ scaledWidth,
+ scaledHeight,
+ hWallpaperDC,
+ 0,
+ 0,
+ gspv.cxWallpaper,
+ gspv.cyWallpaper,
+ SRCCOPY,
+ 0);
+ }
+ }
+ else if (gspv.WallpaperMode == wmFill)
+ {
+ if (Rect.right && Rect.bottom)
+ {
+ NtGdiStretchBlt(hDC,
+ x,
+ y,
+ sz.cx,
+ sz.cy,
+ hWallpaperDC,
+ wallpaperX,
+ wallpaperY,
+ wallpaperWidth,
+ wallpaperHeight,
+ SRCCOPY,
+ 0);
+ }
+ }
else
{
NtGdiBitBlt(hDC,
// We expect at most 4 strings (3 for version, 1 for optional NtSystemRoot)
static POLYTEXTW VerStrs[4] = {{0},{0},{0},{0}};
INT i = 0;
- INT len;
+ SIZE_T len;
HFONT hFont1 = NULL, hFont2 = NULL, hOldFont = NULL;
COLORREF crText, color_old;
PWCHAR pstr = wszzVersion;
for (i = 0; (i < ARRAYSIZE(VerStrs)) && *pstr; ++i)
{
- VerStrs[i].n = wcslen(pstr);
+ VerStrs[i].n = lstrlenW(pstr);
VerStrs[i].lpstr = pstr;
pstr += (VerStrs[i].n + 1);
}
* @implemented
*/
-HDESK APIENTRY
-NtUserCreateDesktop(
- POBJECT_ATTRIBUTES ObjectAttributes,
- PUNICODE_STRING lpszDesktopDevice,
- LPDEVMODEW lpdmw,
- DWORD dwFlags,
- ACCESS_MASK dwDesiredAccess)
+NTSTATUS
+FASTCALL
+IntCreateDesktop(
+ OUT HDESK* phDesktop,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN KPROCESSOR_MODE AccessMode,
+ IN PUNICODE_STRING lpszDesktopDevice OPTIONAL,
+ IN LPDEVMODEW lpdmw OPTIONAL,
+ IN DWORD dwFlags,
+ IN ACCESS_MASK dwDesiredAccess)
{
+ NTSTATUS Status;
PDESKTOP pdesk = NULL;
- NTSTATUS Status = STATUS_SUCCESS;
- HDESK hdesk;
+ HDESK hDesk;
BOOLEAN Context = FALSE;
UNICODE_STRING ClassName;
LARGE_STRING WindowName;
PTHREADINFO ptiCurrent;
PCLS pcls;
- DECLARE_RETURN(HDESK);
+ TRACE("Enter IntCreateDesktop\n");
- TRACE("Enter NtUserCreateDesktop\n");
- UserEnterExclusive();
+ ASSERT(phDesktop);
+ *phDesktop = NULL;
ptiCurrent = PsGetCurrentThreadWin32Thread();
ASSERT(ptiCurrent);
ASSERT(gptiDesktopThread);
- /* Turn off hooks when calling any CreateWindowEx from inside win32k. */
+ /* Turn off hooks when calling any CreateWindowEx from inside win32k */
NoHooks = (ptiCurrent->TIF_flags & TIF_DISABLEHOOKS);
ptiCurrent->TIF_flags |= TIF_DISABLEHOOKS;
ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
/*
* Try to open already existing desktop
*/
- Status = ObOpenObjectByName(
- ObjectAttributes,
- ExDesktopObjectType,
- UserMode,
- NULL,
- dwDesiredAccess,
- (PVOID)&Context,
- (HANDLE*)&hdesk);
+ Status = ObOpenObjectByName(ObjectAttributes,
+ ExDesktopObjectType,
+ AccessMode,
+ NULL,
+ dwDesiredAccess,
+ (PVOID)&Context,
+ (PHANDLE)&hDesk);
if (!NT_SUCCESS(Status))
{
ERR("ObOpenObjectByName failed to open/create desktop\n");
- SetLastNtError(Status);
- RETURN(NULL);
+ goto Quit;
}
/* In case the object was not created (eg if it existed), return now */
if (Context == FALSE)
{
- TRACE("NtUserCreateDesktop opened desktop %wZ\n", ObjectAttributes->ObjectName);
- RETURN( hdesk);
+ TRACE("IntCreateDesktop opened desktop '%wZ'\n", ObjectAttributes->ObjectName);
+ Status = STATUS_SUCCESS;
+ goto Quit;
}
/* Reference the desktop */
- Status = ObReferenceObjectByHandle(hdesk,
+ Status = ObReferenceObjectByHandle(hDesk,
0,
ExDesktopObjectType,
KernelMode,
if (!NT_SUCCESS(Status))
{
ERR("Failed to reference desktop object\n");
- SetLastNtError(Status);
- RETURN(NULL);
+ goto Quit;
}
/* Get the desktop window class. The thread desktop does not belong to any desktop
if (pcls == NULL)
{
ASSERT(FALSE);
- RETURN(NULL);
+ Status = STATUS_UNSUCCESSFUL;
+ goto Quit;
}
RtlZeroMemory(&WindowName, sizeof(WindowName));
Cs.lpszName = (LPCWSTR) &WindowName;
Cs.lpszClass = (LPCWSTR) &ClassName;
- /* Use IntCreateWindow instead of co_UserCreateWindowEx cause the later expects a thread with a desktop */
+ /* Use IntCreateWindow instead of co_UserCreateWindowEx because the later expects a thread with a desktop */
pWnd = IntCreateWindow(&Cs, &WindowName, pcls, NULL, NULL, NULL, pdesk);
if (pWnd == NULL)
{
ERR("Failed to create desktop window for the new desktop\n");
- RETURN(NULL);
+ Status = STATUS_UNSUCCESSFUL;
+ goto Quit;
}
pdesk->dwSessionId = PsGetCurrentProcessSessionId();
if (pcls == NULL)
{
ASSERT(FALSE);
- RETURN(NULL);
+ Status = STATUS_UNSUCCESSFUL;
+ goto Quit;
}
RtlZeroMemory(&WindowName, sizeof(WindowName));
Cs.cx = Cs.cy = 100;
Cs.style = WS_POPUP|WS_CLIPCHILDREN;
Cs.hInstance = hModClient; // hModuleWin; // Server side winproc!
- Cs.lpszName = (LPCWSTR) &WindowName;
- Cs.lpszClass = (LPCWSTR) &ClassName;
+ Cs.lpszName = (LPCWSTR)&WindowName;
+ Cs.lpszClass = (LPCWSTR)&ClassName;
pWnd = IntCreateWindow(&Cs, &WindowName, pcls, NULL, NULL, NULL, pdesk);
if (pWnd == NULL)
{
ERR("Failed to create message window for the new desktop\n");
- RETURN(NULL);
+ Status = STATUS_UNSUCCESSFUL;
+ goto Quit;
}
pdesk->spwndMessage = pWnd;
The rest is same as message window.
http://msdn.microsoft.com/en-us/library/bb760250(VS.85).aspx
*/
- RETURN( hdesk);
+ Status = STATUS_SUCCESS;
-CLEANUP:
+Quit:
if (pdesk != NULL)
{
ObDereferenceObject(pdesk);
}
- if (_ret_ == NULL && hdesk != NULL)
+ if (!NT_SUCCESS(Status) && hDesk != NULL)
{
- ObCloseHandle(hdesk, UserMode);
+ ObCloseHandle(hDesk, AccessMode);
+ hDesk = NULL;
}
if (!NoHooks)
{
ptiCurrent->TIF_flags &= ~TIF_DISABLEHOOKS;
ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
}
- TRACE("Leave NtUserCreateDesktop, ret=%p\n",_ret_);
+
+ TRACE("Leave IntCreateDesktop, Status 0x%08lx\n", Status);
+
+ if (NT_SUCCESS(Status))
+ *phDesktop = hDesk;
+ else
+ SetLastNtError(Status);
+ return Status;
+}
+
+HDESK APIENTRY
+NtUserCreateDesktop(
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ PUNICODE_STRING lpszDesktopDevice,
+ LPDEVMODEW lpdmw,
+ DWORD dwFlags,
+ ACCESS_MASK dwDesiredAccess)
+{
+ NTSTATUS Status;
+ HDESK hDesk;
+
+ DECLARE_RETURN(HDESK);
+
+ TRACE("Enter NtUserCreateDesktop\n");
+ UserEnterExclusive();
+
+ Status = IntCreateDesktop(&hDesk,
+ ObjectAttributes,
+ UserMode,
+ lpszDesktopDevice,
+ lpdmw,
+ dwFlags,
+ dwDesiredAccess);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("IntCreateDesktop failed, Status 0x%08lx\n", Status);
+ // SetLastNtError(Status);
+ RETURN(NULL);
+ }
+
+ RETURN(hDesk);
+
+CLEANUP:
+ TRACE("Leave NtUserCreateDesktop, ret=0x%p\n", _ret_);
UserLeave();
END_CLEANUP;
}
NTSTATUS Status;
DECLARE_RETURN(BOOL);
- TRACE("NtUserCloseDesktop called (0x%p)\n", hDesktop);
+ TRACE("NtUserCloseDesktop(0x%p) called\n", hDesktop);
UserEnterExclusive();
if (hDesktop == gptiCurrent->hdesk || hDesktop == gptiCurrent->ppi->hdeskStartup)
RETURN(FALSE);
}
- Status = IntValidateDesktopHandle( hDesktop, UserMode, 0, &pdesk);
+ Status = IntValidateDesktopHandle(hDesktop, UserMode, 0, &pdesk);
if (!NT_SUCCESS(Status))
{
- ERR("Validation of desktop handle (0x%p) failed\n", hDesktop);
+ ERR("Validation of desktop handle 0x%p failed\n", hDesktop);
RETURN(FALSE);
}
UserEnterExclusive();
TRACE("Enter NtUserSwitchDesktop(0x%p)\n", hdesk);
- Status = IntValidateDesktopHandle( hdesk, UserMode, 0, &pdesk);
+ Status = IntValidateDesktopHandle(hdesk, UserMode, 0, &pdesk);
if (!NT_SUCCESS(Status))
{
- ERR("Validation of desktop handle (0x%p) failed\n", hdesk);
+ ERR("Validation of desktop handle 0x%p failed\n", hdesk);
RETURN(FALSE);
}
NTSTATUS Status;
PETHREAD Thread;
PDESKTOP DesktopObject;
- HDESK Ret, hThreadDesktop;
+ HDESK hDesk, hThreadDesktop;
OBJECT_HANDLE_INFORMATION HandleInformation;
DECLARE_RETURN(HDESK);
{
/* Just return the handle, we queried the desktop handle of a thread running
in the same context */
- Ret = ((PTHREADINFO)Thread->Tcb.Win32Thread)->hdesk;
+ hDesk = ((PTHREADINFO)Thread->Tcb.Win32Thread)->hdesk;
ObDereferenceObject(Thread);
- RETURN(Ret);
+ RETURN(hDesk);
}
/* Get the desktop handle and the desktop of the thread */
/* Lookup our handle table if we can find a handle to the desktop object,
if not, create one */
- Ret = IntGetDesktopObjectHandle(DesktopObject);
+ hDesk = IntGetDesktopObjectHandle(DesktopObject);
/* All done, we got a valid handle to the desktop */
ObDereferenceObject(DesktopObject);
ObDereferenceObject(Thread);
- RETURN(Ret);
+ RETURN(hDesk);
CLEANUP:
TRACE("Leave NtUserGetThreadDesktop, ret=%p\n",_ret_);
if (hDesktop != NULL)
{
/* Validate the new desktop. */
- Status = IntValidateDesktopHandle( hDesktop, UserMode, 0, &pdesk);
+ Status = IntValidateDesktopHandle(hDesktop, UserMode, 0, &pdesk);
if (!NT_SUCCESS(Status))
{
- ERR("Validation of desktop handle (0x%p) failed\n", hDesktop);
+ ERR("Validation of desktop handle 0x%p failed\n", hDesktop);
return FALSE;
}
return FALSE;
}
- pctiNew = DesktopHeapAlloc( pdesk, sizeof(CLIENTTHREADINFO));
+ pctiNew = DesktopHeapAlloc(pdesk, sizeof(CLIENTTHREADINFO));
if (pctiNew == NULL)
{
ERR("Failed to allocate new pcti\n");