PGRAPHICS_DEVICE NTAPI EngpRegisterGraphicsDevice( _In_ PUNICODE_STRING pustrDeviceName, _In_ PUNICODE_STRING pustrDiplayDrivers, _In_ PUNICODE_STRING pustrDescription, _In_ PDEVMODEW pdmDefault) { PGRAPHICS_DEVICE pGraphicsDevice; PDEVICE_OBJECT pDeviceObject; PFILE_OBJECT pFileObject; NTSTATUS Status; PWSTR pwsz; ULONG cj; SIZE_T cjWritten; BOOL bEnable = TRUE; TRACE("EngpRegisterGraphicsDevice(%wZ)\n", pustrDeviceName); /* Allocate a GRAPHICS_DEVICE structure */ pGraphicsDevice = ExAllocatePoolWithTag(PagedPool, sizeof(GRAPHICS_DEVICE), GDITAG_GDEVICE); if (!pGraphicsDevice) { ERR("ExAllocatePoolWithTag failed\n"); return NULL; } /* Try to open the driver */ Status = IoGetDeviceObjectPointer(pustrDeviceName, FILE_READ_DATA | FILE_WRITE_DATA, &pFileObject, &pDeviceObject); if (!NT_SUCCESS(Status)) { ERR("Could not open driver %wZ, 0x%lx\n", pustrDeviceName, Status); ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); return NULL; } /* Enable the device */ EngFileWrite(pFileObject, &bEnable, sizeof(BOOL), &cjWritten); /* Copy the device and file object pointers */ pGraphicsDevice->DeviceObject = pDeviceObject; pGraphicsDevice->FileObject = pFileObject; /* Copy device name */ RtlStringCbCopyNW(pGraphicsDevice->szNtDeviceName, sizeof(pGraphicsDevice->szNtDeviceName), pustrDeviceName->Buffer, pustrDeviceName->Length); /* Create a win device name (FIXME: virtual devices!) */ swprintf(pGraphicsDevice->szWinDeviceName, L"\\\\.\\DISPLAY%d", (int)giDevNum); /* Allocate a buffer for the strings */ cj = pustrDiplayDrivers->Length + pustrDescription->Length + sizeof(WCHAR); pwsz = ExAllocatePoolWithTag(PagedPool, cj, GDITAG_DRVSUP); if (!pwsz) { ERR("Could not allocate string buffer\n"); ASSERT(FALSE); // FIXME ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); return NULL; } /* Copy display driver names */ pGraphicsDevice->pDiplayDrivers = pwsz; RtlCopyMemory(pGraphicsDevice->pDiplayDrivers, pustrDiplayDrivers->Buffer, pustrDiplayDrivers->Length); /* Copy description */ pGraphicsDevice->pwszDescription = pwsz + pustrDiplayDrivers->Length / sizeof(WCHAR); RtlCopyMemory(pGraphicsDevice->pwszDescription, pustrDescription->Buffer, pustrDescription->Length); pGraphicsDevice->pwszDescription[pustrDescription->Length/sizeof(WCHAR)] = 0; /* Initialize the pdevmodeInfo list and default index */ pGraphicsDevice->pdevmodeInfo = NULL; pGraphicsDevice->iDefaultMode = 0; pGraphicsDevice->iCurrentMode = 0; // FIXME: initialize state flags pGraphicsDevice->StateFlags = 0; /* Create the mode list */ pGraphicsDevice->pDevModeList = NULL; if (!EngpPopulateDeviceModeList(pGraphicsDevice, pdmDefault)) { ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); return NULL; } /* Lock loader */ EngAcquireSemaphore(ghsemGraphicsDeviceList); /* Insert the device into the global list */ pGraphicsDevice->pNextGraphicsDevice = NULL; if (gpGraphicsDeviceLast) gpGraphicsDeviceLast->pNextGraphicsDevice = pGraphicsDevice; gpGraphicsDeviceLast = pGraphicsDevice; if (!gpGraphicsDeviceFirst) gpGraphicsDeviceFirst = pGraphicsDevice; /* Increment device number */ giDevNum++; /* Unlock loader */ EngReleaseSemaphore(ghsemGraphicsDeviceList); TRACE("Prepared %lu modes for %ls\n", pGraphicsDevice->cDevModes, pGraphicsDevice->pwszDescription); return pGraphicsDevice; }
/* 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; }
static BOOLEAN CheckForValidPEAndVendor( IN HANDLE RootDirectory OPTIONAL, IN PCWSTR PathNameToFile, OUT PUSHORT Machine, OUT PUNICODE_STRING VendorName) { BOOLEAN Success = FALSE; NTSTATUS Status; HANDLE FileHandle, SectionHandle; // SIZE_T ViewSize; PVOID ViewBase; PIMAGE_NT_HEADERS NtHeader; PVOID VersionBuffer = NULL; // Read-only PVOID pvData = NULL; UINT BufLen = 0; if (VendorName->MaximumLength < sizeof(UNICODE_NULL)) return FALSE; *VendorName->Buffer = UNICODE_NULL; VendorName->Length = 0; Status = OpenAndMapFile(RootDirectory, PathNameToFile, &FileHandle, &SectionHandle, &ViewBase, NULL, FALSE); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to open and map file '%S', Status 0x%08lx\n", PathNameToFile, Status); return FALSE; // Status; } /* Make sure it's a valid NT PE file */ NtHeader = RtlImageNtHeader(ViewBase); if (!NtHeader) { DPRINT1("File '%S' does not seem to be a valid NT PE file, bail out\n", PathNameToFile); Status = STATUS_INVALID_IMAGE_FORMAT; goto UnmapCloseFile; } /* Retrieve the target architecture of this PE module */ *Machine = NtHeader->FileHeader.Machine; /* * Search for a valid executable version and vendor. * NOTE: The module is loaded as a data file, it should be marked as such. */ Status = NtGetVersionResource((PVOID)((ULONG_PTR)ViewBase | 1), &VersionBuffer, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to get version resource for file '%S', Status 0x%08lx\n", PathNameToFile, Status); goto UnmapCloseFile; } Status = NtVerQueryValue(VersionBuffer, L"\\VarFileInfo\\Translation", &pvData, &BufLen); if (NT_SUCCESS(Status)) { USHORT wCodePage = 0, wLangID = 0; WCHAR FileInfo[MAX_PATH]; wCodePage = LOWORD(*(ULONG*)pvData); wLangID = HIWORD(*(ULONG*)pvData); RtlStringCchPrintfW(FileInfo, ARRAYSIZE(FileInfo), L"StringFileInfo\\%04X%04X\\CompanyName", wCodePage, wLangID); Status = NtVerQueryValue(VersionBuffer, FileInfo, &pvData, &BufLen); /* Fixup the Status in case pvData is NULL */ if (NT_SUCCESS(Status) && !pvData) Status = STATUS_NOT_FOUND; if (NT_SUCCESS(Status) /*&& pvData*/) { /* BufLen includes the NULL terminator count */ DPRINT("Found version vendor: \"%S\" for file '%S'\n", pvData, PathNameToFile); RtlStringCbCopyNW(VendorName->Buffer, VendorName->MaximumLength, pvData, BufLen * sizeof(WCHAR)); VendorName->Length = wcslen(VendorName->Buffer) * sizeof(WCHAR); Success = TRUE; } } if (!NT_SUCCESS(Status)) DPRINT("No version vendor found for file '%S'\n", PathNameToFile); UnmapCloseFile: /* Finally, unmap and close the file */ UnMapAndCloseFile(FileHandle, SectionHandle, ViewBase); return Success; }
PGRAPHICS_DEVICE NTAPI EngpRegisterGraphicsDevice( PUNICODE_STRING pustrDeviceName, PUNICODE_STRING pustrDiplayDrivers, PUNICODE_STRING pustrDescription, PDEVMODEW pdmDefault) { PGRAPHICS_DEVICE pGraphicsDevice; PDEVICE_OBJECT pDeviceObject; PFILE_OBJECT pFileObject; NTSTATUS Status; PWSTR pwsz; ULONG i, cj, cModes = 0; SIZE_T cjWritten; BOOL bEnable = TRUE; PDEVMODEINFO pdminfo; PDEVMODEW pdm, pdmEnd; PLDEVOBJ pldev; BOOLEAN bModeMatch = FALSE; TRACE("EngpRegisterGraphicsDevice(%wZ)\n", pustrDeviceName); /* Allocate a GRAPHICS_DEVICE structure */ pGraphicsDevice = ExAllocatePoolWithTag(PagedPool, sizeof(GRAPHICS_DEVICE), GDITAG_GDEVICE); if (!pGraphicsDevice) { ERR("ExAllocatePoolWithTag failed\n"); return NULL; } /* Try to open the driver */ Status = IoGetDeviceObjectPointer(pustrDeviceName, FILE_READ_DATA | FILE_WRITE_DATA, &pFileObject, &pDeviceObject); if (!NT_SUCCESS(Status)) { ERR("Could not open driver %wZ, 0x%lx\n", pustrDeviceName, Status); ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); return NULL; } /* Enable the device */ EngFileWrite(pFileObject, &bEnable, sizeof(BOOL), &cjWritten); /* Copy the device and file object pointers */ pGraphicsDevice->DeviceObject = pDeviceObject; pGraphicsDevice->FileObject = pFileObject; /* Copy device name */ RtlStringCbCopyNW(pGraphicsDevice->szNtDeviceName, sizeof(pGraphicsDevice->szNtDeviceName), pustrDeviceName->Buffer, pustrDeviceName->Length); /* Create a win device name (FIXME: virtual devices!) */ swprintf(pGraphicsDevice->szWinDeviceName, L"\\\\.\\DISPLAY%d", (int)giDevNum); /* Allocate a buffer for the strings */ cj = pustrDiplayDrivers->Length + pustrDescription->Length + sizeof(WCHAR); pwsz = ExAllocatePoolWithTag(PagedPool, cj, GDITAG_DRVSUP); if (!pwsz) { ERR("Could not allocate string buffer\n"); ASSERT(FALSE); // FIXME ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); return NULL; } /* Copy display driver names */ pGraphicsDevice->pDiplayDrivers = pwsz; RtlCopyMemory(pGraphicsDevice->pDiplayDrivers, pustrDiplayDrivers->Buffer, pustrDiplayDrivers->Length); /* Copy description */ pGraphicsDevice->pwszDescription = pwsz + pustrDiplayDrivers->Length / sizeof(WCHAR); RtlCopyMemory(pGraphicsDevice->pwszDescription, pustrDescription->Buffer, pustrDescription->Length); pGraphicsDevice->pwszDescription[pustrDescription->Length/sizeof(WCHAR)] = 0; /* Initialize the pdevmodeInfo list and default index */ pGraphicsDevice->pdevmodeInfo = NULL; pGraphicsDevice->iDefaultMode = 0; pGraphicsDevice->iCurrentMode = 0; // FIXME: initialize state flags pGraphicsDevice->StateFlags = 0; /* Loop through the driver names * This is a REG_MULTI_SZ string */ for (; *pwsz; pwsz += wcslen(pwsz) + 1) { TRACE("trying driver: %ls\n", pwsz); /* Try to load the display driver */ pldev = EngLoadImageEx(pwsz, LDEV_DEVICE_DISPLAY); if (!pldev) { ERR("Could not load driver: '%ls'\n", pwsz); continue; } /* Get the mode list from the driver */ pdminfo = LDEVOBJ_pdmiGetModes(pldev, pDeviceObject); if (!pdminfo) { ERR("Could not get mode list for '%ls'\n", pwsz); continue; } /* Attach the mode info to the device */ pdminfo->pdmiNext = pGraphicsDevice->pdevmodeInfo; pGraphicsDevice->pdevmodeInfo = pdminfo; /* Loop all DEVMODEs */ pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode); for (pdm = pdminfo->adevmode; (pdm + 1 <= pdmEnd) && (pdm->dmSize != 0); pdm = (DEVMODEW*)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra)) { /* Count this DEVMODE */ cModes++; /* Some drivers like the VBox driver don't fill the dmDeviceName with the name of the display driver. So fix that here. */ wcsncpy(pdm->dmDeviceName, pwsz, CCHDEVICENAME); pdm->dmDeviceName[CCHDEVICENAME - 1] = 0; } // FIXME: release the driver again until it's used? } if (!pGraphicsDevice->pdevmodeInfo || cModes == 0) { ERR("No devmodes\n"); ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); return NULL; } /* Allocate an index buffer */ pGraphicsDevice->cDevModes = cModes; pGraphicsDevice->pDevModeList = ExAllocatePoolWithTag(PagedPool, cModes * sizeof(DEVMODEENTRY), GDITAG_GDEVICE); if (!pGraphicsDevice->pDevModeList) { ERR("No devmode list\n"); ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); return NULL; } TRACE("Looking for mode %lux%lux%lu(%lu Hz)\n", pdmDefault->dmPelsWidth, pdmDefault->dmPelsHeight, pdmDefault->dmBitsPerPel, pdmDefault->dmDisplayFrequency); /* Loop through all DEVMODEINFOs */ for (pdminfo = pGraphicsDevice->pdevmodeInfo, i = 0; pdminfo; pdminfo = pdminfo->pdmiNext) { /* Calculate End of the DEVMODEs */ pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode); /* Loop through the DEVMODEs */ for (pdm = pdminfo->adevmode; (pdm + 1 <= pdmEnd) && (pdm->dmSize != 0); pdm = (PDEVMODEW)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra)) { TRACE(" %S has mode %lux%lux%lu(%lu Hz)\n", pdm->dmDeviceName, pdm->dmPelsWidth, pdm->dmPelsHeight, pdm->dmBitsPerPel, pdm->dmDisplayFrequency); /* Compare with the default entry */ if (!bModeMatch && pdm->dmBitsPerPel == pdmDefault->dmBitsPerPel && pdm->dmPelsWidth == pdmDefault->dmPelsWidth && pdm->dmPelsHeight == pdmDefault->dmPelsHeight) { pGraphicsDevice->iDefaultMode = i; pGraphicsDevice->iCurrentMode = i; TRACE("Found default entry: %lu '%ls'\n", i, pdm->dmDeviceName); if (pdm->dmDisplayFrequency == pdmDefault->dmDisplayFrequency) { /* Uh oh, even the display frequency matches. */ bModeMatch = TRUE; } } /* Initialize the entry */ pGraphicsDevice->pDevModeList[i].dwFlags = 0; pGraphicsDevice->pDevModeList[i].pdm = pdm; i++; } } /* Lock loader */ EngAcquireSemaphore(ghsemGraphicsDeviceList); /* Insert the device into the global list */ pGraphicsDevice->pNextGraphicsDevice = NULL; if (gpGraphicsDeviceLast) gpGraphicsDeviceLast->pNextGraphicsDevice = pGraphicsDevice; gpGraphicsDeviceLast = pGraphicsDevice; if (!gpGraphicsDeviceFirst) gpGraphicsDeviceFirst = pGraphicsDevice; /* Increment device number */ giDevNum++; /* Unlock loader */ EngReleaseSemaphore(ghsemGraphicsDeviceList); TRACE("Prepared %lu modes for %ls\n", cModes, pGraphicsDevice->pwszDescription); return pGraphicsDevice; }