PMONITOR FASTCALL UserMonitorFromPoint( IN POINT pt, IN DWORD dwFlags) { RECTL rc; HMONITOR hMonitor = NULL; /* Check if flags are valid */ if (dwFlags != MONITOR_DEFAULTTONULL && dwFlags != MONITOR_DEFAULTTOPRIMARY && dwFlags != MONITOR_DEFAULTTONEAREST) { EngSetLastError(ERROR_INVALID_FLAGS); return NULL; } /* Fill rect (bottom-right exclusive) */ rc.left = pt.x; rc.right = pt.x + 1; rc.top = pt.y; rc.bottom = pt.y + 1; /* Find intersecting monitor */ IntGetMonitorsFromRect(&rc, &hMonitor, NULL, 1, dwFlags); return UserGetMonitorObject(hMonitor); }
/* NtUserGetMonitorInfo * * Retrieves information about a given monitor * * Arguments * * hMonitor * Handle to a monitor for which to get information * * pMonitorInfo * Pointer to a MONITORINFO struct which is filled with the information. * The cbSize member must be set to sizeof(MONITORINFO) or * sizeof(MONITORINFOEX). Even if set to sizeof(MONITORINFOEX) only parts * from MONITORINFO will be filled. * * pDevice * Pointer to a UNICODE_STRING which will recieve the device's name. The * length should be CCHDEVICENAME * Can be NULL * * Return value * TRUE on success; FALSE on failure (calls SetLastNtError()) * */ BOOL APIENTRY NtUserGetMonitorInfo( IN HMONITOR hMonitor, OUT LPMONITORINFO pMonitorInfo) { PMONITOR Monitor; MONITORINFOEXW MonitorInfo; NTSTATUS Status; DECLARE_RETURN(BOOL); TRACE("Enter NtUserGetMonitorInfo\n"); UserEnterShared(); /* get monitor object */ if (!(Monitor = UserGetMonitorObject(hMonitor))) { TRACE("Couldnt find monitor 0x%lx\n", hMonitor); RETURN(FALSE); } if(pMonitorInfo == NULL) { SetLastNtError(STATUS_INVALID_PARAMETER); RETURN(FALSE); } /* get size of pMonitorInfo */ Status = MmCopyFromCaller(&MonitorInfo.cbSize, &pMonitorInfo->cbSize, sizeof (MonitorInfo.cbSize)); if (!NT_SUCCESS(Status)) { SetLastNtError(Status); RETURN(FALSE); } if ((MonitorInfo.cbSize != sizeof (MONITORINFO)) && (MonitorInfo.cbSize != sizeof (MONITORINFOEXW))) { SetLastNtError(STATUS_INVALID_PARAMETER); RETURN(FALSE); } /* fill monitor info */ MonitorInfo.rcMonitor = Monitor->rcMonitor; MonitorInfo.rcWork = Monitor->rcWork; MonitorInfo.dwFlags = 0; if (Monitor->IsPrimary) MonitorInfo.dwFlags |= MONITORINFOF_PRIMARY; /* fill device name */ if (MonitorInfo.cbSize == sizeof (MONITORINFOEXW)) { RtlStringCbCopyNW(MonitorInfo.szDevice, sizeof(MonitorInfo.szDevice), Monitor->DeviceName.Buffer, Monitor->DeviceName.Length); } /* output data */ Status = MmCopyToCaller(pMonitorInfo, &MonitorInfo, MonitorInfo.cbSize); if (!NT_SUCCESS(Status)) { TRACE("GetMonitorInfo: MmCopyToCaller failed\n"); SetLastNtError(Status); RETURN(FALSE); } TRACE("GetMonitorInfo: success\n"); RETURN(TRUE); CLEANUP: TRACE("Leave NtUserGetMonitorInfo, ret=%i\n",_ret_); UserLeave(); END_CLEANUP; }
/* NtUserGetMonitorInfo * * Retrieves information about a given monitor * * Arguments * * hMonitor * Handle to a monitor for which to get information * * pMonitorInfoUnsafe * Pointer to a MONITORINFO struct which is filled with the information. * The cbSize member must be set to sizeof(MONITORINFO) or * sizeof(MONITORINFOEX). Even if set to sizeof(MONITORINFOEX) only parts * from MONITORINFO will be filled. * * pDevice * Pointer to a UNICODE_STRING which will receive the device's name. The * length should be CCHDEVICENAME * Can be NULL * * Return value * TRUE on success; FALSE on failure (calls SetLastNtError()) * */ BOOL APIENTRY NtUserGetMonitorInfo( IN HMONITOR hMonitor, OUT LPMONITORINFO pMonitorInfoUnsafe) { PMONITOR pMonitor; MONITORINFOEXW MonitorInfo; NTSTATUS Status; BOOL bRet = FALSE; PWCHAR pwstrDeviceName; TRACE("Enter NtUserGetMonitorInfo\n"); UserEnterShared(); /* Get monitor object */ pMonitor = UserGetMonitorObject(hMonitor); if (!pMonitor) { TRACE("Couldnt find monitor %p\n", hMonitor); goto cleanup; } /* Check if pMonitorInfoUnsafe is valid */ if(pMonitorInfoUnsafe == NULL) { SetLastNtError(STATUS_INVALID_PARAMETER); goto cleanup; } pwstrDeviceName = ((PPDEVOBJ)(pMonitor->hDev))->pGraphicsDevice->szWinDeviceName; /* Get size of pMonitorInfoUnsafe */ Status = MmCopyFromCaller(&MonitorInfo.cbSize, &pMonitorInfoUnsafe->cbSize, sizeof(MonitorInfo.cbSize)); if (!NT_SUCCESS(Status)) { SetLastNtError(Status); goto cleanup; } /* Check if size of struct is valid */ if (MonitorInfo.cbSize != sizeof(MONITORINFO) && MonitorInfo.cbSize != sizeof(MONITORINFOEXW)) { SetLastNtError(STATUS_INVALID_PARAMETER); goto cleanup; } /* Fill monitor info */ MonitorInfo.rcMonitor = pMonitor->rcMonitor; MonitorInfo.rcWork = pMonitor->rcWork; MonitorInfo.dwFlags = 0; if (pMonitor->IsPrimary) MonitorInfo.dwFlags |= MONITORINFOF_PRIMARY; /* Fill device name */ if (MonitorInfo.cbSize == sizeof(MONITORINFOEXW)) { RtlStringCbCopyNExW(MonitorInfo.szDevice, sizeof(MonitorInfo.szDevice), pwstrDeviceName, (wcslen(pwstrDeviceName)+1) * sizeof(WCHAR), NULL, NULL, STRSAFE_FILL_BEHIND_NULL); } /* Output data */ Status = MmCopyToCaller(pMonitorInfoUnsafe, &MonitorInfo, MonitorInfo.cbSize); if (!NT_SUCCESS(Status)) { TRACE("GetMonitorInfo: MmCopyToCaller failed\n"); SetLastNtError(Status); goto cleanup; } TRACE("GetMonitorInfo: success\n"); bRet = TRUE; cleanup: TRACE("Leave NtUserGetMonitorInfo, ret=%i\n", bRet); UserLeave(); return bRet; }
PMONITOR NTAPI UserMonitorFromRect( PRECTL pRect, DWORD dwFlags) { ULONG cMonitors, LargestArea = 0, i; PRECTL prcMonitorList = NULL; HMONITOR *phMonitorList = NULL; HMONITOR hMonitor = NULL; /* Check if flags are valid */ if (dwFlags != MONITOR_DEFAULTTONULL && dwFlags != MONITOR_DEFAULTTOPRIMARY && dwFlags != MONITOR_DEFAULTTONEAREST) { EngSetLastError(ERROR_INVALID_FLAGS); return NULL; } /* Find intersecting monitors */ cMonitors = IntGetMonitorsFromRect(pRect, &hMonitor, NULL, 1, dwFlags); if (cMonitors <= 1) { /* No or one monitor found. Just return handle. */ goto cleanup; } /* There is more than one monitor. Find monitor with largest intersection. Temporary reset hMonitor */ hMonitor = NULL; /* Allocate helper buffers */ phMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof(HMONITOR) * cMonitors, USERTAG_MONITORRECTS); if (phMonitorList == NULL) { EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); goto cleanup; } prcMonitorList = ExAllocatePoolWithTag(PagedPool, sizeof(RECT) * cMonitors, USERTAG_MONITORRECTS); if (prcMonitorList == NULL) { EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); goto cleanup; } /* Get intersecting monitors again but now with rectangle list */ cMonitors = IntGetMonitorsFromRect(pRect, phMonitorList, prcMonitorList, cMonitors, 0); /* Find largest intersection */ for (i = 0; i < cMonitors; i++) { ULONG Area = (prcMonitorList[i].right - prcMonitorList[i].left) * (prcMonitorList[i].bottom - prcMonitorList[i].top); if (Area >= LargestArea) { hMonitor = phMonitorList[i]; LargestArea = Area; } } cleanup: if (phMonitorList) ExFreePoolWithTag(phMonitorList, USERTAG_MONITORRECTS); if (prcMonitorList) ExFreePoolWithTag(prcMonitorList, USERTAG_MONITORRECTS); return UserGetMonitorObject(hMonitor); }