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

📄 winsta.c

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

   WindowStationObject->ScreenSaverRunning = FALSE;
   
   WindowStationObject->FlatMenu = FALSE;

   if(!(CurInfo = ExAllocatePool(PagedPool, sizeof(SYSTEM_CURSORINFO))))
   {
      ExFreePool(FullWindowStationName.Buffer);
      /* FIXME - Delete window station object */
      ObDereferenceObject(WindowStationObject);
      SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
      return 0;
   }

   CurInfo->Enabled = FALSE;
   CurInfo->ButtonsDown = 0;
   CurInfo->CursorClipInfo.IsClipped = FALSE;
   CurInfo->LastBtnDown = 0;
   CurInfo->CurrentCursorObject = NULL;
   CurInfo->ShowingCursor = 0;   

   /* FIXME: Obtain the following information from the registry */    

   CurInfo->WheelScroLines = 3;
   CurInfo->WheelScroChars = 3;
   CurInfo->SwapButtons = FALSE;
   CurInfo->DblClickSpeed = 500;
   CurInfo->DblClickWidth = 4;
   CurInfo->DblClickHeight = 4;

   CurInfo->MouseSpeed = 10;
   CurInfo->CursorAccelerationInfo.FirstThreshold  = 6;
   CurInfo->CursorAccelerationInfo.SecondThreshold = 10;
   CurInfo->CursorAccelerationInfo.Acceleration    = 1;

   CurInfo->MouseHoverTime = 80;
   CurInfo->MouseHoverWidth = 4;
   CurInfo->MouseHoverHeight = 4;

   WindowStationObject->ScreenSaverActive = FALSE;
   WindowStationObject->ScreenSaverTimeOut = 10;
   WindowStationObject->SystemCursor = CurInfo;

   /* END FIXME loading from register */

   if (!IntSetupClipboard(WindowStationObject))
   {
       DPRINT1("WindowStation: Error Setting up the clipboard!!!\n");
   }   
    
   if (!IntSetupCurIconHandles(WindowStationObject))
   {
      DPRINT1("Setting up the Cursor/Icon Handle table failed!\n");
      /* FIXME: Complain more loudly? */
      ExFreePool(FullWindowStationName.Buffer);
   }

   DPRINT("Window station successfully created (%wZ)\n", FullWindowStationName);
   ExFreePool(FullWindowStationName.Buffer);
   return WindowStation;
}

/*
 * NtUserOpenWindowStation
 *
 * Opens an existing window station.
 *
 * Parameters
 *    lpszWindowStationName
 *       Name of the existing window station.
 *
 *    dwDesiredAccess
 *       Requested type of access.
 *
 * Return Value
 *    If the function succeeds, the return value is the handle to the
 *    specified window station. If the function fails, the return value
 *    is NULL.
 *
 * Remarks
 *    The returned handle can be closed with NtUserCloseWindowStation.
 *
 * Status
 *    @implemented
 */

HWINSTA STDCALL
NtUserOpenWindowStation(
   PUNICODE_STRING lpszWindowStationName,
   ACCESS_MASK dwDesiredAccess)
{
   UNICODE_STRING WindowStationName;
   HWINSTA WindowStation;
   OBJECT_ATTRIBUTES ObjectAttributes;
   NTSTATUS Status;

   /*
    * Generate full window station name
    */

   if (!IntGetFullWindowStationName(&WindowStationName, lpszWindowStationName,
                                    NULL))
   {
      SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
      return 0;
   }

   DPRINT("Trying to open window station (%wZ)\n", &WindowStationName);

   /* Initialize ObjectAttributes for the window station object */
   InitializeObjectAttributes(
      &ObjectAttributes,
      &WindowStationName,
      0,
      NULL,
      NULL);

   Status = ObOpenObjectByName(
               &ObjectAttributes,
               ExWindowStationObjectType,
               UserMode,
               NULL,
               dwDesiredAccess,
               NULL,
               (PVOID*)&WindowStation);

   if (!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      ExFreePool(WindowStationName.Buffer);
      return 0;
   }

   DPRINT("Successfully opened window station (%wZ)\n", &WindowStationName);
   ExFreePool(WindowStationName.Buffer);

   return WindowStation;
}

/*
 * NtUserCloseWindowStation
 *
 * Closes a window station handle.
 *
 * Parameters
 *    hWinSta
 *       Handle to the window station.
 *
 * Return Value
 *    Status
 *
 * Remarks
 *    The window station handle can be created with NtUserCreateWindowStation
 *    or NtUserOpenWindowStation. Attemps to close a handle to the window
 *    station assigned to the calling process will fail.
 *
 * Status
 *    @implemented
 */

BOOL
STDCALL
NtUserCloseWindowStation(
   HWINSTA hWinSta)
{
   PWINSTATION_OBJECT Object;
   NTSTATUS Status;

   DPRINT("About to close window station handle (0x%X)\n", hWinSta);

   Status = IntValidateWindowStationHandle(
               hWinSta,
               KernelMode,
               0,
               &Object);

   if (!NT_SUCCESS(Status))
   {
      DPRINT("Validation of window station handle (0x%X) failed\n", hWinSta);
      return FALSE;
   }

#if 0
   /* FIXME - free the cursor information when actually deleting the object!! */
   ASSERT(Object->SystemCursor);
   ExFreePool(Object->SystemCursor);
#endif

   ObDereferenceObject(Object);

   DPRINT("Closing window station handle (0x%X)\n", hWinSta);

   Status = ZwClose(hWinSta);
   if (!NT_SUCCESS(Status))
   {
      SetLastNtError(Status);
      return FALSE;
   }

   return TRUE;
}

/*
 * NtUserGetObjectInformation
 *
 * The NtUserGetObjectInformation function retrieves information about a
 * window station or desktop object.
 *
 * Parameters
 *    hObj
 *       Handle to the window station or desktop object for which to
 *       return information. This can be a handle of type HDESK or HWINSTA
 *       (for example, a handle returned by NtUserCreateWindowStation,
 *       NtUserOpenWindowStation, NtUserCreateDesktop, or NtUserOpenDesktop).
 *
 *    nIndex
 *       Specifies the object information to be retrieved.
 *
 *    pvInfo
 *       Pointer to a buffer to receive the object information.
 *
 *    nLength
 *       Specifies the size, in bytes, of the buffer pointed to by the
 *       pvInfo parameter.
 *
 *    lpnLengthNeeded
 *       Pointer to a variable receiving the number of bytes required to
 *       store the requested information. If this variable's value is
 *       greater than the value of the nLength parameter when the function
 *       returns, the function returns FALSE, and none of the information
 *       is copied to the pvInfo buffer. If the value of the variable pointed
 *       to by lpnLengthNeeded is less than or equal to the value of nLength,
 *       the entire information block is copied.
 *
 * Return Value
 *    If the function succeeds, the return value is nonzero. If the function
 *    fails, the return value is zero.
 *
 * Status
 *    @unimplemented
 */

BOOL STDCALL
NtUserGetObjectInformation(
   HANDLE hObject,
   DWORD nIndex,
   PVOID pvInformation,
   DWORD nLength,
   PDWORD nLengthNeeded)
{
   PWINSTATION_OBJECT WinStaObject = NULL;
   PDESKTOP_OBJECT DesktopObject = NULL;
   NTSTATUS Status;
   PVOID pvData = NULL;
   DWORD nDataSize = 0;

   /* try windowstation */
   DPRINT("Trying to open window station 0x%x\n", hObject);
   Status = IntValidateWindowStationHandle(
               hObject,
               UserMode,/*ExGetPreviousMode(),*/
               GENERIC_READ, /* FIXME: is this ok? */
               &WinStaObject);


   if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_TYPE_MISMATCH)
   {
      DPRINT("Failed: 0x%x\n", Status);
      SetLastNtError(Status);
      return FALSE;
   }

   if (Status == STATUS_OBJECT_TYPE_MISMATCH)
   {
      /* try desktop */
      DPRINT("Trying to open desktop 0x%x\n", hObject);
      Status = IntValidateDesktopHandle(
                  hObject,
                  UserMode,/*ExGetPreviousMode(),*/
                  GENERIC_READ, /* FIXME: is this ok? */
                  &DesktopObject);
      if (!NT_SUCCESS(Status))
      {
         DPRINT("Failed: 0x%x\n", Status);
         SetLastNtError(Status);
         return FALSE;
      }
   }
   DPRINT("WinSta or Desktop opened!!\n");

   /* get data */
   switch (nIndex)
   {
      case UOI_FLAGS:
         Status = STATUS_NOT_IMPLEMENTED;
         DPRINT1("UOI_FLAGS unimplemented!\n");
         break;

      case UOI_NAME:
         if (WinStaObject != NULL)
         {
            pvData = ((PUNICODE_STRING)GET_DESKTOP_NAME(WinStaObject))->Buffer;
            nDataSize = ((PUNICODE_STRING)GET_DESKTOP_NAME(WinStaObject))->Length + 2;
            Status = STATUS_SUCCESS;
         }
         else if (DesktopObject != NULL)
         {
            pvData = ((PUNICODE_STRING)GET_DESKTOP_NAME(DesktopObject))->Buffer;
            nDataSize = ((PUNICODE_STRING)GET_DESKTOP_NAME(DesktopObject))->Length + 2;
            Status = STATUS_SUCCESS;
         }
         else
            Status = STATUS_INVALID_PARAMETER;
         break;

      case UOI_TYPE:
         if (WinStaObject != NULL)
         {
            pvData = L"WindowStation";
            nDataSize = (wcslen(pvData) + 1) * sizeof(WCHAR);
            Status = STATUS_SUCCESS;
         }
         else if (DesktopObject != NULL)
         {
            pvData = L"Desktop";
            nDataSize = (wcslen(pvData) + 1) * sizeof(WCHAR);
            Status = STATUS_SUCCESS;
         }
         else
            Status = STATUS_INVALID_PARAMETER;
         break;

      case UOI_USER_SID:
         Status = STATUS_NOT_IMPLEMENTED;
         DPRINT1("UOI_USER_SID unimplemented!\n");
         break;

      default:
         Status = STATUS_INVALID_PARAMETER;
         break;
   }

   /* try to copy data to caller */
   if (Status == STATUS_SUCCESS)
   {
      DPRINT("Trying to copy data to caller (len = %d, len needed = %d)\n", nLength, nDataSize);
      *nLengthNeeded = nDataSize;
      if (nLength >= nDataSize)
         Status = MmCopyToCaller(pvInformation, pvData, nDataSize);
      else
         Status = STATUS_BUFFER_TOO_SMALL;
   }

   /* release objects */
   if (WinStaObject != NULL)
      ObDereferenceObject(WinStaObject);
   if (DesktopObject != NULL)
      ObDereferenceObject(DesktopObject);

   SetLastNtError(Status);
   return NT_SUCCESS(Status);
}

/*
 * NtUserSetObjectInformation
 *
 * The NtUserSetObjectInformation function sets information about a
 * window station or desktop object.
 *
 * Parameters
 *    hObj
 *       Handle to the window station or desktop object for which to set
 *       object information. This value can be a handle of type HDESK or
 *       HWINSTA.
 *
 *    nIndex
 *       Specifies the object information to be set.
 *
 *    pvInfo
 *       Pointer to a buffer containing the object information.
 *
 *    nLength
 *       Specifies the size, in bytes, of the information contained in the
 *       buffer pointed to by pvInfo.
 *
 * Return Value
 *    If the function succeeds, the return value is nonzero. If the function
 *    fails the return value is zero.
 *
 * Status
 *    @unimplemented
 */

BOOL
STDCALL
NtUserSetObjectInformation(
   HANDLE hObject,
   DWORD nIndex,
   PVOID pvInformation,
   DWORD nLength)
{
   /* FIXME: ZwQueryObject */
   /* FIXME: ZwSetInformationObject */
   SetLastNtError(STATUS_UNSUCCESSFUL);
   return FALSE;
}




HWINSTA FASTCALL
UserGetProcessWindowStation(VOID)
{
   NTSTATUS Status;
   HWINSTA WinSta;

   if(PsGetCurrentProcess() != CsrProcess)
   {
      return PsGetCurrentProcess()->Win32WindowStation;
   }
   else
   {
      DPRINT1("Should use ObFindHandleForObject\n");
      Status = ObOpenObjectByPointer(PsGetCurrentThreadWin32Thread()->Desktop->WindowStation,
                                     0,
                                     NULL,
                                     WINSTA_ALL_ACCESS,
                                     ExWindowStationObjectType,
                                     UserMode,
                                     (PHANDLE) &WinSta);
      if (! NT_SUCCESS(Status))
      {
         SetLastNtError(Status);
         DPRINT1("Unable to open handle for CSRSSs winsta, status 0x%08x\n",
                 Status);
         return NULL;
      }
      return WinSta;
   }
}


/*
 * NtUserGetProcessWindowStation
 *
 * Returns a handle to the current process window station.
 *
 * Return Value
 *    If the function succeeds, the return value is handle to the window
 *    station assigned to the current process. If the function fails, the
 *    return value is NULL.
 *
 * Status
 *    @implemented
 */

HWINSTA STDCALL
NtUserGetProcessWindowStation(VOID)
{
   return UserGetProcessWindowStation();
}

PWINSTATION_OBJECT FASTCALL
IntGetWinStaObj(VOID)
{
   PWINSTATION_OBJECT WinStaObj;

   /*
    * just a temporary hack, this will be gone soon
    */

   if(PsGetCurrentThreadWin32Thread() != NULL && PsGetCurrentThreadWin32Thread()->Desktop != NULL)
   {
      WinStaObj = PsGetCurrentThreadWin32Thread()->Desktop->WindowStation;
      ObReferenceObjectByPointer(WinStaObj, KernelMode, ExWindowStationObjectType, 0);
   }
   else if(PsGetCurrentProcess() != CsrProcess)
   {
      NTSTATUS Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
                        KernelMode,
                        0,
                        &WinStaObj);
      if(!NT_SUCCESS(Status))
      {
         SetLastNtError(Status);
         return NULL;
      }
   }
   else
   {
      WinStaObj = NULL;
   }

   return WinStaObj;
}

/*
 * NtUserSetProcessWindowStation

⌨️ 快捷键说明

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