📄 desktop.c
字号:
RtlZeroMemory(DesktopObject->DesktopInfo,
DesktopInfoSize);
DesktopObject->DesktopInfo->hKernelHeap = DesktopObject->hDesktopHeap;
RtlCopyMemory(DesktopObject->DesktopInfo->szDesktopName,
lpszDesktopName->Buffer,
lpszDesktopName->Length);
// init desktop area
DesktopObject->WorkArea.left = 0;
DesktopObject->WorkArea.top = 0;
DesktopObject->WorkArea.right = -1;
DesktopObject->WorkArea.bottom = -1;
IntGetDesktopWorkArea(DesktopObject, NULL);
/* Initialize some local (to win32k) desktop state. */
DesktopObject->ActiveMessageQueue = NULL;
ExFreePool(DesktopName.Buffer);
if (! NT_SUCCESS(Status))
{
DPRINT1("Failed to create desktop handle\n");
SetLastNtError(Status);
RETURN( NULL);
}
/*
* Create a handle for CSRSS and notify CSRSS
*/
Request.Type = MAKE_CSR_API(CREATE_DESKTOP, CSR_GUI);
Status = CsrInsertObject(Desktop,
GENERIC_ALL,
(HANDLE*)&Request.Data.CreateDesktopRequest.DesktopHandle);
if (! NT_SUCCESS(Status))
{
DPRINT1("Failed to create desktop handle for CSRSS\n");
ZwClose(Desktop);
SetLastNtError(Status);
RETURN( NULL);
}
Status = co_CsrNotify(&Request);
if (! NT_SUCCESS(Status))
{
CsrCloseHandle(Request.Data.CreateDesktopRequest.DesktopHandle);
DPRINT1("Failed to notify CSRSS about new desktop\n");
ZwClose(Desktop);
SetLastNtError(Status);
RETURN( NULL);
}
RETURN( Desktop);
CLEANUP:
DPRINT("Leave NtUserCreateDesktop, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/*
* NtUserOpenDesktop
*
* Opens an existing desktop.
*
* Parameters
* lpszDesktopName
* Name of the existing desktop.
*
* dwFlags
* Interaction flags.
*
* dwDesiredAccess
* Requested type of access.
*
* Return Value
* Handle to the desktop or zero on failure.
*
* Status
* @implemented
*/
HDESK STDCALL
NtUserOpenDesktop(
PUNICODE_STRING lpszDesktopName,
DWORD dwFlags,
ACCESS_MASK dwDesiredAccess)
{
OBJECT_ATTRIBUTES ObjectAttributes;
HWINSTA WinSta;
PWINSTATION_OBJECT WinStaObject;
UNICODE_STRING DesktopName;
UNICODE_STRING SafeDesktopName;
NTSTATUS Status;
HDESK Desktop;
BOOL Result;
DECLARE_RETURN(HDESK);
DPRINT("Enter NtUserOpenDesktop: %wZ\n", lpszDesktopName);
UserEnterExclusive();
/*
* Validate the window station handle and compose the fully
* qualified desktop name
*/
WinSta = UserGetProcessWindowStation();
Status = IntValidateWindowStationHandle(
WinSta,
KernelMode,
0,
&WinStaObject);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed validation of window station handle (0x%X)\n", WinSta);
SetLastNtError(Status);
RETURN( 0);
}
if(lpszDesktopName != NULL)
{
Status = IntSafeCopyUnicodeString(&SafeDesktopName, lpszDesktopName);
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
RETURN( NULL);
}
}
else
{
RtlInitUnicodeString(&SafeDesktopName, NULL);
}
Result = IntGetFullWindowStationName(&DesktopName, &WinStaObject->Name,
&SafeDesktopName);
RtlFreeUnicodeString(&SafeDesktopName);
ObDereferenceObject(WinStaObject);
if (!Result)
{
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
RETURN( 0);
}
DPRINT("Trying to open desktop (%wZ)\n", &DesktopName);
/* Initialize ObjectAttributes for the desktop object */
InitializeObjectAttributes(
&ObjectAttributes,
&DesktopName,
0,
NULL,
NULL);
Status = ObOpenObjectByName(
&ObjectAttributes,
ExDesktopObjectType,
KernelMode,
NULL,
dwDesiredAccess,
NULL,
(HANDLE*)&Desktop);
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
ExFreePool(DesktopName.Buffer);
RETURN( 0);
}
DPRINT("Successfully opened desktop (%wZ)\n", &DesktopName);
ExFreePool(DesktopName.Buffer);
RETURN( Desktop);
CLEANUP:
DPRINT("Leave NtUserOpenDesktop, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/*
* NtUserOpenInputDesktop
*
* Opens the input (interactive) desktop.
*
* Parameters
* dwFlags
* Interaction flags.
*
* fInherit
* Inheritance option.
*
* dwDesiredAccess
* Requested type of access.
*
* Return Value
* Handle to the input desktop or zero on failure.
*
* Status
* @implemented
*/
HDESK STDCALL
NtUserOpenInputDesktop(
DWORD dwFlags,
BOOL fInherit,
ACCESS_MASK dwDesiredAccess)
{
PDESKTOP_OBJECT Object;
NTSTATUS Status;
HDESK Desktop;
DECLARE_RETURN(HDESK);
DPRINT("Enter NtUserOpenInputDesktop\n");
UserEnterExclusive();
DPRINT("About to open input desktop\n");
/* Get a pointer to the desktop object */
Status = IntValidateDesktopHandle(
InputDesktopHandle,
UserMode,
0,
&Object);
if (!NT_SUCCESS(Status))
{
DPRINT("Validation of input desktop handle (0x%X) failed\n", InputDesktop);
RETURN((HDESK)0);
}
/* Create a new handle to the object */
Status = ObOpenObjectByPointer(
Object,
0,
NULL,
dwDesiredAccess,
ExDesktopObjectType,
UserMode,
(HANDLE*)&Desktop);
ObDereferenceObject(Object);
if (NT_SUCCESS(Status))
{
DPRINT("Successfully opened input desktop\n");
RETURN((HDESK)Desktop);
}
SetLastNtError(Status);
RETURN((HDESK)0);
CLEANUP:
DPRINT("Leave NtUserOpenInputDesktop, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/*
* NtUserCloseDesktop
*
* Closes a desktop handle.
*
* Parameters
* hDesktop
* Handle to the desktop.
*
* Return Value
* Status
*
* Remarks
* The desktop handle can be created with NtUserCreateDesktop or
* NtUserOpenDesktop. This function will fail if any thread in the calling
* process is using the specified desktop handle or if the handle refers
* to the initial desktop of the calling process.
*
* Status
* @implemented
*/
BOOL STDCALL
NtUserCloseDesktop(HDESK hDesktop)
{
PDESKTOP_OBJECT Object;
NTSTATUS Status;
DECLARE_RETURN(BOOL);
DPRINT("Enter NtUserCloseDesktop\n");
UserEnterExclusive();
DPRINT("About to close desktop handle (0x%X)\n", hDesktop);
Status = IntValidateDesktopHandle(
hDesktop,
UserMode,
0,
&Object);
if (!NT_SUCCESS(Status))
{
DPRINT("Validation of desktop handle (0x%X) failed\n", hDesktop);
RETURN(FALSE);
}
ObDereferenceObject(Object);
DPRINT("Closing desktop handle (0x%X)\n", hDesktop);
Status = ZwClose(hDesktop);
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
RETURN(FALSE);
}
RETURN(TRUE);
CLEANUP:
DPRINT("Leave NtUserCloseDesktop, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/*
* NtUserPaintDesktop
*
* The NtUserPaintDesktop function fills the clipping region in the
* specified device context with the desktop pattern or wallpaper. The
* function is provided primarily for shell desktops.
*
* Parameters
* hDC
* Handle to the device context.
*
* Status
* @implemented
*/
BOOL STDCALL
NtUserPaintDesktop(HDC hDC)
{
RECT Rect;
HBRUSH DesktopBrush, PreviousBrush;
HWND hWndDesktop;
BOOL doPatBlt = TRUE;
PWINDOW_OBJECT WndDesktop;
int len;
COLORREF color_old;
UINT align_old;
int mode_old;
PWINSTATION_OBJECT WinSta = PsGetCurrentThreadWin32Thread()->Desktop->WindowStation;
DECLARE_RETURN(BOOL);
UserEnterExclusive();
DPRINT("Enter NtUserPaintDesktop\n");
IntGdiGetClipBox(hDC, &Rect);
hWndDesktop = IntGetDesktopWindow();
WndDesktop = UserGetWindowObject(hWndDesktop);
if (!WndDesktop)
{
RETURN(FALSE);
}
DesktopBrush = (HBRUSH)UserGetClassLongPtr(WndDesktop->Class, GCL_HBRBACKGROUND, FALSE);
/*
* Paint desktop background
*/
if (WinSta->hbmWallpaper != NULL)
{
PWINDOW_OBJECT DeskWin;
DeskWin = UserGetWindowObject(hWndDesktop);
if (DeskWin)
{
SIZE sz;
int x, y;
HDC hWallpaperDC;
sz.cx = DeskWin->WindowRect.right - DeskWin->WindowRect.left;
sz.cy = DeskWin->WindowRect.bottom - DeskWin->WindowRect.top;
if (WinSta->WallpaperMode == wmStretch ||
WinSta->WallpaperMode == wmTile)
{
x = 0;
y = 0;
}
else
{
/* Find the upper left corner, can be negtive if the bitmap is bigger then the screen */
x = (sz.cx / 2) - (WinSta->cxWallpaper / 2);
y = (sz.cy / 2) - (WinSta->cyWallpaper / 2);
}
hWallpaperDC = NtGdiCreateCompatibleDC(hDC);
if(hWallpaperDC != NULL)
{
HBITMAP hOldBitmap;
/* fill in the area that the bitmap is not going to cover */
if (x > 0 || y > 0)
{
/* FIXME - clip out the bitmap
can be replaced with "NtGdiPatBlt(hDC, x, y, WinSta->cxWallpaper, WinSta->cyWallpaper, PATCOPY | DSTINVERT);"
once we support DSTINVERT */
PreviousBrush = NtGdiSelectObject(hDC, DesktopBrush);
NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom, PATCOPY);
NtGdiSelectObject(hDC, PreviousBrush);
}
/*Do not fill the background after it is painted no matter the size of the picture */
doPatBlt = FALSE;
hOldBitmap = NtGdiSelectObject(hWallpaperDC, WinSta->hbmWallpaper);
if (WinSta->WallpaperMode == wmStretch)
{
if(Rect.right && Rect.bottom)
NtGdiStretchBlt(hDC,
x,
y,
sz.cx,
sz.cy,
hWallpaperDC,
0,
0,
WinSta->cxWallpaper,
WinSta->cyWallpaper,
SRCCOPY,
0);
}
else if (WinSta->WallpaperMode == wmTile)
{
/* paint the bitmap across the screen then down */
for(y = 0; y < Rect.bottom; y += WinSta->cyWallpaper)
{
for(x = 0; x < Rect.right; x += WinSta->cxWallpaper)
{
NtGdiBitBlt(hDC,
x,
y,
WinSta->cxWallpaper,
WinSta->cyWallpaper,
hWallpaperDC,
0,
0,
SRCCOPY,
0,
0);
}
}
}
else
{
NtGdiBitBlt(hDC,
x,
y,
WinSta->cxWallpaper,
WinSta->cyWallpaper,
hWallpaperDC,
0,
0,
SRCCOPY,
0,
0);
}
NtGdiSelectObject(hWallpaperDC, hOldBitmap);
NtGdiDeleteObjectApp(hWallpaperDC);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -