Example #1
0
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;
}
Example #2
0
/* 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;
}
Example #3
0
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;
}
Example #4
0
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;
}