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

📄 cursoricon.c

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

   WinSta = IntGetWinStaObj();
   if(WinSta == NULL)
   {
      RETURN( (HANDLE)0);
   }

   if (!(CurIcon = IntCreateCurIconHandle(WinSta)))
   {
      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
      ObDereferenceObject(WinSta);
      RETURN( (HANDLE)0);
   }
   
   Ret = CurIcon->Self;

   if(IconInfo)
   {
      Status = MmCopyFromCaller(&CurIcon->IconInfo, IconInfo, sizeof(ICONINFO));
      if(NT_SUCCESS(Status))
      {
         if(Indirect)
         {
            CurIcon->IconInfo.hbmMask = BITMAPOBJ_CopyBitmap(CurIcon->IconInfo.hbmMask);
            CurIcon->IconInfo.hbmColor = BITMAPOBJ_CopyBitmap(CurIcon->IconInfo.hbmColor);
         }
         if(CurIcon->IconInfo.hbmColor &&
               (bmp = BITMAPOBJ_LockBitmap(CurIcon->IconInfo.hbmColor)))
         {
            CurIcon->Size.cx = bmp->SurfObj.sizlBitmap.cx;
            CurIcon->Size.cy = bmp->SurfObj.sizlBitmap.cy;
            BITMAPOBJ_UnlockBitmap(bmp);
            GDIOBJ_SetOwnership(GdiHandleTable, CurIcon->IconInfo.hbmColor, NULL);
         }
         if(CurIcon->IconInfo.hbmMask &&
               (bmp = BITMAPOBJ_LockBitmap(CurIcon->IconInfo.hbmMask)))
         {
            if (CurIcon->IconInfo.hbmColor == NULL)
            {
               CurIcon->Size.cx = bmp->SurfObj.sizlBitmap.cx;
               CurIcon->Size.cy = bmp->SurfObj.sizlBitmap.cy / 2;
            }
            BITMAPOBJ_UnlockBitmap(bmp);
            GDIOBJ_SetOwnership(GdiHandleTable, CurIcon->IconInfo.hbmMask, NULL);
         }
      }
      else
      {
         SetLastNtError(Status);
         /* FIXME - Don't exit here */
      }
   }

   ObDereferenceObject(WinSta);
   RETURN( Ret);

CLEANUP:
   DPRINT("Leave NtUserCreateCursorIconHandle, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}

/*
 * @implemented
 */
BOOL
STDCALL
NtUserGetCursorIconInfo(
   HANDLE hCurIcon,
   PICONINFO IconInfo)
{
   ICONINFO ii;
   PCURICON_OBJECT CurIcon;
   PWINSTATION_OBJECT WinSta;
   NTSTATUS Status;
   BOOL Ret = FALSE;
   DECLARE_RETURN(BOOL);

   DPRINT("Enter NtUserGetCursorIconInfo\n");
   UserEnterExclusive();

   if(!IconInfo)
   {
      SetLastWin32Error(ERROR_INVALID_PARAMETER);
      RETURN(FALSE);
   }

   WinSta = IntGetWinStaObj();
   if(WinSta == NULL)
   {
      RETURN( FALSE);
   }

   if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
   {
      ObDereferenceObject(WinSta);
      RETURN( FALSE);
   }
   
   RtlCopyMemory(&ii, &CurIcon->IconInfo, sizeof(ICONINFO));

   /* Copy bitmaps */
   ii.hbmMask = BITMAPOBJ_CopyBitmap(ii.hbmMask);
   ii.hbmColor = BITMAPOBJ_CopyBitmap(ii.hbmColor);

   /* Copy fields */
   Status = MmCopyToCaller(IconInfo, &ii, sizeof(ICONINFO));
   if(NT_SUCCESS(Status))
      Ret = TRUE;
   else
      SetLastNtError(Status);

   ObDereferenceObject(WinSta);
   RETURN( Ret);

CLEANUP:
   DPRINT("Leave NtUserGetCursorIconInfo, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}


/*
 * @implemented
 */
BOOL
STDCALL
NtUserGetCursorIconSize(
   HANDLE hCurIcon,
   BOOL *fIcon,
   SIZE *Size)
{
   PCURICON_OBJECT CurIcon;
   PBITMAPOBJ bmp;
   PWINSTATION_OBJECT WinSta;
   NTSTATUS Status;
   BOOL Ret = FALSE;
   SIZE SafeSize;
   DECLARE_RETURN(BOOL);

   DPRINT("Enter NtUserGetCursorIconSize\n");
   UserEnterExclusive();

   WinSta = IntGetWinStaObj();
   if(WinSta == NULL)
   {
      RETURN( FALSE);
   }

   if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
   {
      ObDereferenceObject(WinSta);
      RETURN(FALSE);
   }
   
   /* Copy fields */
   Status = MmCopyToCaller(fIcon, &CurIcon->IconInfo.fIcon, sizeof(BOOL));
   if(!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      goto done;
   }

   bmp = BITMAPOBJ_LockBitmap(CurIcon->IconInfo.hbmColor);
   if(!bmp)
      goto done;

   SafeSize.cx = bmp->SurfObj.sizlBitmap.cx;
   SafeSize.cy = bmp->SurfObj.sizlBitmap.cy;
   Status = MmCopyToCaller(Size, &SafeSize, sizeof(SIZE));
   if(NT_SUCCESS(Status))
      Ret = TRUE;
   else
      SetLastNtError(Status);

   BITMAPOBJ_UnlockBitmap(bmp);

done:
   ObDereferenceObject(WinSta);
   RETURN( Ret);

CLEANUP:
   DPRINT("Leave NtUserGetCursorIconSize, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}


/*
 * @unimplemented
 */
DWORD
STDCALL
NtUserGetCursorFrameInfo(
   DWORD Unknown0,
   DWORD Unknown1,
   DWORD Unknown2,
   DWORD Unknown3)
{
   UNIMPLEMENTED

   return 0;
}


/*
 * @implemented
 */
BOOL
STDCALL
NtUserGetCursorInfo(
   PCURSORINFO pci)
{
   CURSORINFO SafeCi;
   PSYSTEM_CURSORINFO CurInfo;
   PWINSTATION_OBJECT WinSta;
   NTSTATUS Status;
   PCURICON_OBJECT CurIcon;
   HDC hDC;
   DECLARE_RETURN(BOOL);

   DPRINT("Enter NtUserGetCursorInfo\n");
   UserEnterExclusive();

#if 1


   /* FIXME - get the screen dc from the window station or desktop */
   if (!(hDC = IntGetScreenDC()))
   {
      RETURN( FALSE);
   }
#endif

   Status = MmCopyFromCaller(&SafeCi.cbSize, pci, sizeof(DWORD));
   if(!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      RETURN( FALSE);
   }

   if(SafeCi.cbSize != sizeof(CURSORINFO))
   {
      SetLastWin32Error(ERROR_INVALID_PARAMETER);
      RETURN( FALSE);
   }

   WinSta = IntGetWinStaObj();
   if(WinSta == NULL)
   {
      RETURN( FALSE);
   }

   CurInfo = IntGetSysCursorInfo(WinSta);
   CurIcon = (PCURICON_OBJECT)CurInfo->CurrentCursorObject;

   SafeCi.flags = ((CurInfo->ShowingCursor && CurIcon) ? CURSOR_SHOWING : 0);
   SafeCi.hCursor = (CurIcon ? (HCURSOR)CurIcon->Self : (HCURSOR)0);

   IntGetCursorLocation(WinSta, &SafeCi.ptScreenPos);

   Status = MmCopyToCaller(pci, &SafeCi, sizeof(CURSORINFO));
   if(!NT_SUCCESS(Status))
   {
      ObDereferenceObject(WinSta);
      SetLastNtError(Status);
      RETURN( FALSE);
   }

   ObDereferenceObject(WinSta);
   RETURN( TRUE);

CLEANUP:
   DPRINT("Leave NtUserGetCursorInfo, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}


/*
 * @implemented
 */
BOOL
STDCALL
NtUserClipCursor(
   RECT *UnsafeRect)
{
   /* FIXME - check if process has WINSTA_WRITEATTRIBUTES */

   PWINSTATION_OBJECT WinSta;
   PSYSTEM_CURSORINFO CurInfo;
   RECT Rect;
   PWINDOW_OBJECT DesktopWindow = NULL;
   POINT MousePos = {0};
   DECLARE_RETURN(BOOL);

   DPRINT("Enter NtUserClipCursor\n");
   UserEnterExclusive();

   WinSta = IntGetWinStaObj();
   if (WinSta == NULL)
   {
      RETURN( FALSE);
   }

   if (NULL != UnsafeRect && ! NT_SUCCESS(MmCopyFromCaller(&Rect, UnsafeRect, sizeof(RECT))))
   {
      ObDereferenceObject(WinSta);
      SetLastWin32Error(ERROR_INVALID_PARAMETER);
      RETURN( FALSE);
   }

   CurInfo = IntGetSysCursorInfo(WinSta);
   IntGetCursorLocation(WinSta, &MousePos);

   if(WinSta->ActiveDesktop)
      DesktopWindow = UserGetWindowObject(WinSta->ActiveDesktop->DesktopWindow);

   if((Rect.right > Rect.left) && (Rect.bottom > Rect.top)
         && DesktopWindow && UnsafeRect != NULL)
   {
      MOUSEINPUT mi;

      CurInfo->CursorClipInfo.IsClipped = TRUE;
      CurInfo->CursorClipInfo.Left = max(Rect.left, DesktopWindow->WindowRect.left);
      CurInfo->CursorClipInfo.Top = max(Rect.top, DesktopWindow->WindowRect.top);
      CurInfo->CursorClipInfo.Right = min(Rect.right - 1, DesktopWindow->WindowRect.right - 1);
      CurInfo->CursorClipInfo.Bottom = min(Rect.bottom - 1, DesktopWindow->WindowRect.bottom - 1);

      mi.dx = MousePos.x;
      mi.dy = MousePos.y;
      mi.mouseData = 0;
      mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
      mi.time = 0;
      mi.dwExtraInfo = 0;
      IntMouseInput(&mi);

      RETURN( TRUE);
   }

   CurInfo->CursorClipInfo.IsClipped = FALSE;
   ObDereferenceObject(WinSta);

   RETURN( TRUE);

CLEANUP:
   DPRINT("Leave NtUserClipCursor, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}


/*
 * @implemented
 */
BOOL
STDCALL
NtUserDestroyCursorIcon(
   HANDLE hCurIcon,
   DWORD Unknown)
{
   PWINSTATION_OBJECT WinSta;
   PCURICON_OBJECT CurIcon;
   BOOL ret;
   DECLARE_RETURN(BOOL);

   DPRINT("Enter NtUserDestroyCursorIcon\n");
   UserEnterExclusive();

   WinSta = IntGetWinStaObj();
   if(WinSta == NULL)
   {
      RETURN( FALSE);
   }

   if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
   {
      ObDereferenceObject(WinSta);
      RETURN(FALSE);
   }

   ret = IntDestroyCurIconObject(WinSta, CurIcon, FALSE);

   ObDereferenceObject(WinSta);
   RETURN(ret);

CLEANUP:
   DPRINT("Leave NtUserDestroyCursorIcon, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}


/*
 * @implemented
 */
HICON
STDCALL
NtUserFindExistingCursorIcon(
   HMODULE hModule,
   HRSRC hRsrc,
   LONG cx,
   LONG cy)
{
   PCURICON_OBJECT CurIcon;
   PWINSTATION_OBJECT WinSta;
   HANDLE Ret = (HANDLE)0;
   DECLARE_RETURN(HICON);

   DPRINT("Enter NtUserFindExistingCursorIcon\n");
   UserEnterExclusive();

   WinSta = IntGetWinStaObj();
   if(WinSta == NULL)
   {
      RETURN( Ret);
   }

   CurIcon = IntFindExistingCurIconObject(WinSta, hModule, hRsrc, cx, cy);
   if(CurIcon)
   {
      Ret = CurIcon->Self;

//      IntReleaseCurIconObject(CurIcon);//faxme: is this correct? does IntFindExistingCurIconObject add a ref?
      ObDereferenceObject(WinSta);
      RETURN( Ret);
   }

   SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
   ObDereferenceObject(WinSta);
   RETURN( (HANDLE)0);

CLEANUP:
   DPRINT("Leave NtUserFindExistingCursorIcon, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}


/*
 * @implemented
 */
BOOL
STDCALL
NtUserGetClipCursor(
   RECT *lpRect)
{
   /* FIXME - check if process has WINSTA_READATTRIBUTES */
   PSYSTEM_CURSORINFO CurInfo;
   PWINSTATION_OBJECT WinSta;
   RECT Rect;
   NTSTATUS Status;
   DECLARE_RETURN(BOOL);

   DPRINT("Enter NtUserGetClipCursor\n");
   UserEnterExclusive();

   if(!lpRect)
      RETURN( FALSE);

   WinSta = IntGetWinStaObj();
   if (WinSta == NULL)
   {
      RETURN( FALSE);
   }

   CurInfo = IntGetSysCursorInfo(WinSta);
   if(CurInfo->CursorClipInfo.IsClipped)
   {
      Rect.left = CurInfo->CursorClipInfo.Left;
      Rect.top = CurInfo->CursorClipInfo.Top;
      Rect.right = CurInfo->CursorClipInfo.Right;
      Rect.bottom = CurInfo->CursorClipInfo.Bottom;
   }
   else
   {
      Rect.left = 0;
      Rect.top = 0;
      Rect.right = UserGetSystemMetrics(SM_CXSCREEN);
      Rect.bottom = UserGetSystemMetrics(SM_CYSCREEN);
   }

   Status = MmCopyToCaller((PRECT)lpRect, &Rect, sizeof(RECT));
   if(!NT_SUCCESS(Status))
   {
      ObDereferenceObject(WinSta);
      SetLastNtError(Status);
      RETURN( FALSE);
   }

   ObDereferenceObject(WinSta);

   RETURN( TRUE);

CLEANUP:
   DPRINT("Leave NtUserGetClipCursor, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}


/*
 * @implemented
 */
HCURSOR
STDCALL
NtUserSetCursor(
   HCURSOR hCursor)
{
   PCURICON_OBJECT CurIcon;
   HICON OldCursor;
   PWINSTATION_OBJECT WinSta;
   DECLARE_RETURN(HCURSOR);

   DPRINT("Enter NtUserSetCursor\n");
   UserEnterExclusive();

   WinSta = IntGetWinStaObj();
   if(WinSta == NULL)
   {
      RETURN(NULL);
   }
   
   if(!(CurIcon = UserGetCurIconObject(hCursor)))
   {
      ObDereferenceObject(WinSta);
      RETURN(NULL);
   }
   
   OldCursor = IntSetCursor(WinSta, CurIcon, FALSE);

   ObDereferenceObject(WinSta);
   
   RETURN(OldCursor);

CLEANUP:
   DPRINT("Leave NtUserSetCursor, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}


/*
 * @implemented
 */
BOOL
STDCALL
NtUserSetCursorIconContents(
   HANDLE hCurIcon,
   PICONINFO IconInfo)
{
   PCURICON_OBJECT CurIcon;
   PBITMAPOBJ bmp;
   PWINSTATION_OBJECT WinSta;
   NTSTATUS Status;
   BOOL Ret = FALSE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -