⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 desktop.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:

   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 + -