ReactOS 0.4.15-dev-5895-g2687c1b
ldevobj.c File Reference
#include <win32k.h>
#include <debug.h>
Include dependency graph for ldevobj.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define RVA_TO_ADDR(Base, Rva)   ((PVOID)(((ULONG_PTR)(Base)) + (Rva)))
 
#define DM_DIFF(field)   (RequestedMode->field > pdmCurrent->field ? (RequestedMode->field - pdmCurrent->field) : (pdmCurrent->field - RequestedMode->field))
 

Functions

 DBG_DEFAULT_CHANNEL (EngLDev)
 
NTSTATUS NTAPI InitLDEVImpl (VOID)
 
static PLDEVOBJ LDEVOBJ_AllocLDEV (_In_ LDEVTYPE ldevtype)
 
static VOID LDEVOBJ_vFreeLDEV (_In_ _Post_ptr_invalid_ PLDEVOBJ pldev)
 
static BOOL LDEVOBJ_bLoadImage (_Inout_ PLDEVOBJ pldev, _In_ PUNICODE_STRING pustrPathName)
 
static BOOL LDEVOBJ_bEnableDriver (_Inout_ PLDEVOBJ pldev, _In_ PFN_DrvEnableDriver pfnEnableDriver)
 
static VOID LDEVOBJ_vDisableDriver (_Inout_ PLDEVOBJ pldev)
 
static PVOID LDEVOBJ_pvFindImageProcAddress (_In_ PLDEVOBJ pldev, _In_z_ LPSTR pszProcName)
 
static BOOL LDEVOBJ_bUnloadImage (_Inout_ PLDEVOBJ pldev)
 
PLDEVOBJ LDEVOBJ_pLoadInternal (_In_ PFN_DrvEnableDriver pfnEnableDriver, _In_ ULONG ldevtype)
 
PLDEVOBJ NTAPI LDEVOBJ_pLoadDriver (_In_z_ LPWSTR pwszDriverName, _In_ ULONG ldevtype)
 
static VOID LDEVOBJ_vDereference (_Inout_ PLDEVOBJ pldev)
 
ULONG LDEVOBJ_ulGetDriverModes (_In_ LPWSTR pwszDriverName, _In_ HANDLE hDriver, _Out_ PDEVMODEW *ppdm)
 
BOOL LDEVOBJ_bBuildDevmodeList (_Inout_ PGRAPHICS_DEVICE pGraphicsDevice)
 
static BOOL LDEVOBJ_bGetClosestMode (_Inout_ PGRAPHICS_DEVICE pGraphicsDevice, _In_ PDEVMODEW RequestedMode, _Out_ PDEVMODEW *pSelectedMode)
 
BOOL LDEVOBJ_bProbeAndCaptureDevmode (_Inout_ PGRAPHICS_DEVICE pGraphicsDevice, _In_ PDEVMODEW RequestedMode, _Out_ PDEVMODEW *pSelectedMode, _In_ BOOL bSearchClosestMode)
 
HANDLE APIENTRY EngLoadImage (_In_ LPWSTR pwszDriverName)
 
VOID APIENTRY EngUnloadImage (_In_ HANDLE hModule)
 
PVOID APIENTRY EngFindImageProcAddress (_In_ HANDLE hModule, _In_ LPSTR lpProcName)
 

Variables

static HSEMAPHORE ghsemLDEVList
 
static LIST_ENTRY gleLdevListHead
 
static LDEVOBJgpldevWin32k = NULL
 

Macro Definition Documentation

◆ DM_DIFF

#define DM_DIFF (   field)    (RequestedMode->field > pdmCurrent->field ? (RequestedMode->field - pdmCurrent->field) : (pdmCurrent->field - RequestedMode->field))

◆ NDEBUG

#define NDEBUG

Definition at line 10 of file ldevobj.c.

◆ RVA_TO_ADDR

#define RVA_TO_ADDR (   Base,
  Rva 
)    ((PVOID)(((ULONG_PTR)(Base)) + (Rva)))

Definition at line 15 of file ldevobj.c.

Function Documentation

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( EngLDev  )

◆ EngFindImageProcAddress()

PVOID APIENTRY EngFindImageProcAddress ( _In_ HANDLE  hModule,
_In_ LPSTR  lpProcName 
)

Definition at line 925 of file ldevobj.c.

928{
929 PLDEVOBJ pldev = (PLDEVOBJ)hModule;
930
932
933 /* Check if win32k is requested */
934 if (!pldev)
935 {
936 pldev = gpldevWin32k;
937 }
938
939 /* Check if the drivers entry point is requested */
940 if (_strnicmp(lpProcName, "DrvEnableDriver", 15) == 0)
941 {
942 return pldev->pGdiDriverInfo->EntryPoint;
943 }
944
945 /* Try to find the address */
946 return LDEVOBJ_pvFindImageProcAddress(pldev, lpProcName);
947}
#define NULL
Definition: types.h:112
HMODULE hModule
Definition: animate.c:44
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
static PVOID LDEVOBJ_pvFindImageProcAddress(_In_ PLDEVOBJ pldev, _In_z_ LPSTR pszProcName)
Definition: ldevobj.c:223
static LDEVOBJ * gpldevWin32k
Definition: ldevobj.c:22
struct _LDEVOBJ * PLDEVOBJ
#define ASSERT(a)
Definition: mode.c:44
SYSTEM_GDI_DRIVER_INFORMATION * pGdiDriverInfo
Definition: ldevobj.h:19

Referenced by DxDdStartupDxGraphics(), and UserLoadKbdDll().

◆ EngLoadImage()

HANDLE APIENTRY EngLoadImage ( _In_ LPWSTR  pwszDriverName)

Exported functions

Definition at line 902 of file ldevobj.c.

904{
905 return (HANDLE)LDEVOBJ_pLoadDriver(pwszDriverName, LDEV_IMAGE);
906}
PLDEVOBJ NTAPI LDEVOBJ_pLoadDriver(_In_z_ LPWSTR pwszDriverName, _In_ ULONG ldevtype)
Definition: ldevobj.c:347
@ LDEV_IMAGE
Definition: ldevobj.h:12

Referenced by DxDdStartupDxGraphics(), and UserLoadKbdDll().

◆ EngUnloadImage()

VOID APIENTRY EngUnloadImage ( _In_ HANDLE  hModule)

Definition at line 911 of file ldevobj.c.

913{
914 PLDEVOBJ pldev = (PLDEVOBJ)hModule;
915
916 /* Make sure the LDEV is in the list */
917 ASSERT((pldev->leLink.Flink != NULL) && (pldev->leLink.Blink != NULL));
918
920}
static VOID LDEVOBJ_vDereference(_Inout_ PLDEVOBJ pldev)
Definition: ldevobj.c:468
LIST_ENTRY leLink
Definition: ldevobj.h:18
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121

Referenced by DxDdStartupDxGraphics(), PDEVOBJ_Create(), PDEVOBJ_vRelease(), UnloadKbdFile(), and UserLoadKbdDll().

◆ InitLDEVImpl()

NTSTATUS NTAPI InitLDEVImpl ( VOID  )

Private functions

Definition at line 30 of file ldevobj.c.

31{
32 ULONG cbSize;
33
34 /* Initialize the LDEV list head */
36
37 /* Initialize the loader lock */
39 if (!ghsemLDEVList)
40 {
41 ERR("Failed to create ghsemLDEVList\n");
43 }
44
45 /* Allocate a LDEVOBJ for win32k */
47 sizeof(LDEVOBJ) +
50 if (!gpldevWin32k)
51 {
52 return STATUS_NO_MEMORY;
53 }
54
55 /* Initialize the LDEVOBJ for win32k */
63 L"\\SystemRoot\\System32\\win32k.sys");
69 TRUE,
71 &cbSize);
73
74 return STATUS_SUCCESS;
75}
#define ERR(fmt,...)
Definition: debug.h:110
#define __ImageBase
Definition: crt_handler.c:22
#define TRUE
Definition: types.h:120
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PagedPool
Definition: env_spec_w32.h:308
HSEMAPHORE WINAPI EngCreateSemaphore(VOID)
Definition: eng.c:75
static LIST_ENTRY gleLdevListHead
Definition: ldevobj.c:21
static HSEMAPHORE ghsemLDEVList
Definition: ldevobj.c:20
@ LDEV_DEVICE_DISPLAY
Definition: ldevobj.h:8
static const unsigned GDI_ENGINE_VERSION
Definition: ldevobj.h:4
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define L(x)
Definition: ntvdm.h:50
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG cRefs
Definition: ldevobj.h:21
ULONG ulDriverVersion
Definition: ldevobj.h:22
LDEVTYPE ldevtype
Definition: ldevobj.h:20
PIMAGE_EXPORT_DIRECTORY ExportSectionPointer
Definition: DriverTester.h:49
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define GDITAG_LDEV
Definition: tags.h:136

Referenced by DriverEntry().

◆ LDEVOBJ_AllocLDEV()

static PLDEVOBJ LDEVOBJ_AllocLDEV ( _In_ LDEVTYPE  ldevtype)
static

Definition at line 79 of file ldevobj.c.

81{
82 PLDEVOBJ pldev;
83
84 /* Allocate the structure from paged pool */
86 if (!pldev)
87 {
88 ERR("Failed to allocate LDEVOBJ.\n");
89 return NULL;
90 }
91
92 /* Zero out the structure */
93 RtlZeroMemory(pldev, sizeof(LDEVOBJ));
94
95 /* Set the ldevtype */
96 pldev->ldevtype = ldevtype;
97
98 return pldev;
99}
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by LDEVOBJ_pLoadDriver(), and LDEVOBJ_pLoadInternal().

◆ LDEVOBJ_bBuildDevmodeList()

BOOL LDEVOBJ_bBuildDevmodeList ( _Inout_ PGRAPHICS_DEVICE  pGraphicsDevice)

Definition at line 563 of file ldevobj.c.

565{
566 PWSTR pwsz;
567 PDEVMODEINFO pdminfo;
568 PDEVMODEW pdm, pdmEnd;
569 ULONG i, cModes = 0;
570 ULONG cbSize, cbFull;
571
572 if (pGraphicsDevice->pdevmodeInfo)
573 return TRUE;
574 ASSERT(pGraphicsDevice->pDevModeList == NULL);
575
576 pwsz = pGraphicsDevice->pDiplayDrivers;
577
578 /* Loop through the driver names
579 * This is a REG_MULTI_SZ string */
580 for (; *pwsz; pwsz += wcslen(pwsz) + 1)
581 {
582 /* Get the mode list from the driver */
583 TRACE("Trying driver: %ls\n", pwsz);
584 cbSize = LDEVOBJ_ulGetDriverModes(pwsz, pGraphicsDevice->DeviceObject, &pdm);
585 if (!cbSize)
586 {
587 WARN("Driver %ls returned no valid mode\n", pwsz);
588 continue;
589 }
590
591 /* Add space for the header */
592 cbFull = cbSize + FIELD_OFFSET(DEVMODEINFO, adevmode);
593
594 /* Allocate a buffer for the DEVMODE array */
596 if (!pdminfo)
597 {
598 ERR("Could not allocate devmodeinfo\n");
600 continue;
601 }
602
603 pdminfo->cbdevmode = cbSize;
604 RtlCopyMemory(pdminfo->adevmode, pdm, cbSize);
606
607 /* Attach the mode info to the device */
608 pdminfo->pdmiNext = pGraphicsDevice->pdevmodeInfo;
609 pGraphicsDevice->pdevmodeInfo = pdminfo;
610
611 /* Loop all DEVMODEs */
612 pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode);
613 for (pdm = pdminfo->adevmode;
614 (pdm + 1 <= pdmEnd) && (pdm->dmSize != 0);
615 pdm = (DEVMODEW*)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
616 {
617 /* Count this DEVMODE */
618 cModes++;
619
620 /* Some drivers like the VBox driver don't fill the dmDeviceName
621 with the name of the display driver. So fix that here. */
622 RtlStringCbCopyW(pdm->dmDeviceName, sizeof(pdm->dmDeviceName), pwsz);
623 }
624 }
625
626 if (!pGraphicsDevice->pdevmodeInfo || cModes == 0)
627 {
628 ERR("No devmodes\n");
629 return FALSE;
630 }
631
632 /* Allocate an index buffer */
633 pGraphicsDevice->cDevModes = cModes;
634 pGraphicsDevice->pDevModeList = ExAllocatePoolWithTag(PagedPool,
635 cModes * sizeof(DEVMODEENTRY),
637 if (!pGraphicsDevice->pDevModeList)
638 {
639 ERR("No devmode list\n");
640 return FALSE;
641 }
642
643 /* Loop through all DEVMODEINFOs */
644 for (pdminfo = pGraphicsDevice->pdevmodeInfo, i = 0;
645 pdminfo;
646 pdminfo = pdminfo->pdmiNext)
647 {
648 /* Calculate End of the DEVMODEs */
649 pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode);
650
651 /* Loop through the DEVMODEs */
652 for (pdm = pdminfo->adevmode;
653 (pdm + 1 <= pdmEnd) && (pdm->dmSize != 0);
654 pdm = (PDEVMODEW)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra))
655 {
656 TRACE(" %S has mode %lux%lux%lu(%lu Hz)\n",
657 pdm->dmDeviceName,
658 pdm->dmPelsWidth,
659 pdm->dmPelsHeight,
660 pdm->dmBitsPerPel,
661 pdm->dmDisplayFrequency);
662
663 /* Initialize the entry */
664 pGraphicsDevice->pDevModeList[i].dwFlags = 0;
665 pGraphicsDevice->pDevModeList[i].pdm = pdm;
666 i++;
667 }
668 }
669 return TRUE;
670}
#define WARN(fmt,...)
Definition: debug.h:112
#define FALSE
Definition: types.h:117
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
ULONG LDEVOBJ_ulGetDriverModes(_In_ LPWSTR pwszDriverName, _In_ HANDLE hDriver, _Out_ PDEVMODEW *ppdm)
Definition: ldevobj.c:509
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
NTSTRSAFEAPI RtlStringCbCopyW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:174
#define TRACE(s)
Definition: solgame.cpp:4
struct _DEVMODEINFO * pdmiNext
Definition: pdevobj.h:44
DEVMODEW adevmode[1]
Definition: pdevobj.h:47
ULONG cbdevmode
Definition: pdevobj.h:46
DWORD dmBitsPerPel
Definition: wingdi.h:1647
WCHAR dmDeviceName[CCHDEVICENAME]
Definition: wingdi.h:1617
DWORD dmPelsWidth
Definition: wingdi.h:1648
WORD dmDriverExtra
Definition: wingdi.h:1621
DWORD dmPelsHeight
Definition: wingdi.h:1649
DWORD dmDisplayFrequency
Definition: wingdi.h:1654
WORD dmSize
Definition: wingdi.h:1620
uint16_t * PWSTR
Definition: typedefs.h:56
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
char * PCHAR
Definition: typedefs.h:51
#define GDITAG_DEVMODE
Definition: tags.h:73
#define GDITAG_GDEVICE
Definition: tags.h:99
struct _devicemodeW * PDEVMODEW

Referenced by LDEVOBJ_bProbeAndCaptureDevmode(), and PDEVOBJ_vRefreshModeList().

◆ LDEVOBJ_bEnableDriver()

static BOOL LDEVOBJ_bEnableDriver ( _Inout_ PLDEVOBJ  pldev,
_In_ PFN_DrvEnableDriver  pfnEnableDriver 
)
static

Definition at line 165 of file ldevobj.c.

168{
169 DRVENABLEDATA ded;
170 ULONG i;
171
172 TRACE("LDEVOBJ_bEnableDriver('%wZ')\n", &pldev->pGdiDriverInfo->DriverName);
173
174 ASSERT(pldev);
175 ASSERT(pldev->cRefs == 0);
176
177 if (pldev->ldevtype == LDEV_IMAGE)
178 return TRUE;
179
180 /* Call the drivers DrvEnableDriver function */
181 RtlZeroMemory(&ded, sizeof(ded));
182 if (!pfnEnableDriver(GDI_ENGINE_VERSION, sizeof(ded), &ded))
183 {
184 ERR("DrvEnableDriver failed\n");
185 return FALSE;
186 }
187
188 /* Copy the returned driver version */
189 pldev->ulDriverVersion = ded.iDriverVersion;
190
191 /* Fill the driver function array */
192 for (i = 0; i < ded.c; i++)
193 {
194 pldev->apfn[ded.pdrvfn[i].iFunc] = ded.pdrvfn[i].pfn;
195 }
196
197 /* Return success. */
198 return TRUE;
199}
PFN pfn
Definition: winddi.h:531
ULONG iFunc
Definition: winddi.h:530
ULONG iDriverVersion
Definition: winddi.h:542
DRVFN * pdrvfn
Definition: winddi.h:544

Referenced by LDEVOBJ_pLoadDriver(), LDEVOBJ_pLoadInternal(), and LDEVOBJ_vDereference().

◆ LDEVOBJ_bGetClosestMode()

static BOOL LDEVOBJ_bGetClosestMode ( _Inout_ PGRAPHICS_DEVICE  pGraphicsDevice,
_In_ PDEVMODEW  RequestedMode,
_Out_ PDEVMODEW pSelectedMode 
)
static

Definition at line 676 of file ldevobj.c.

680{
681 DEVMODEW dmDiff;
682 PDEVMODEW pdmCurrent, pdmBest = NULL;
683 ULONG i;
684
685 /* Use a DEVMODE to keep the differences between best mode found and expected mode.
686 * Initialize fields to max value so we can find better modes. */
687 dmDiff.dmPelsWidth = 0xffffffff;
688 dmDiff.dmPelsHeight = 0xffffffff;
689 dmDiff.dmBitsPerPel = 0xffffffff;
690 dmDiff.dmDisplayFrequency = 0xffffffff;
691
692 /* Search the closest mode */
693#define DM_DIFF(field) (RequestedMode->field > pdmCurrent->field ? (RequestedMode->field - pdmCurrent->field) : (pdmCurrent->field - RequestedMode->field))
694 for (i = 0; i < pGraphicsDevice->cDevModes; i++)
695 {
696 pdmCurrent = pGraphicsDevice->pDevModeList[i].pdm;
697
698 /* Skip current mode if it is worse than best mode found */
699 if (RequestedMode->dmPelsWidth != 0 && DM_DIFF(dmPelsWidth) > dmDiff.dmPelsWidth)
700 continue;
701 if (RequestedMode->dmPelsHeight != 0 && DM_DIFF(dmPelsHeight) > dmDiff.dmPelsHeight)
702 continue;
703 if (RequestedMode->dmBitsPerPel != 0 && DM_DIFF(dmBitsPerPel) > dmDiff.dmBitsPerPel)
704 continue;
705 if (RequestedMode->dmDisplayFrequency != 0 && DM_DIFF(dmDisplayFrequency) > dmDiff.dmDisplayFrequency)
706 continue;
707
708 /* Better (or equivalent) mode found. Update differences */
709 dmDiff.dmPelsWidth = DM_DIFF(dmPelsWidth);
710 dmDiff.dmPelsHeight = DM_DIFF(dmPelsHeight);
711 dmDiff.dmBitsPerPel = DM_DIFF(dmBitsPerPel);
712 dmDiff.dmDisplayFrequency = DM_DIFF(dmDisplayFrequency);
713 pdmBest = pdmCurrent;
714 }
715#undef DM_DIFF
716
717 if (pdmBest)
718 {
719 TRACE("Closest display mode to '%dx%dx%d %d Hz' is '%dx%dx%d %d Hz'\n",
720 RequestedMode->dmPelsWidth,
721 RequestedMode->dmPelsHeight,
722 RequestedMode->dmBitsPerPel,
723 RequestedMode->dmDisplayFrequency,
724 pdmBest->dmPelsWidth,
725 pdmBest->dmPelsHeight,
726 pdmBest->dmBitsPerPel,
727 pdmBest->dmDisplayFrequency);
728 }
729
730 *pSelectedMode = pdmBest;
731 return pdmBest != NULL;
732}
#define DM_DIFF(field)

Referenced by LDEVOBJ_bProbeAndCaptureDevmode().

◆ LDEVOBJ_bLoadImage()

static BOOL LDEVOBJ_bLoadImage ( _Inout_ PLDEVOBJ  pldev,
_In_ PUNICODE_STRING  pustrPathName 
)
static

Definition at line 116 of file ldevobj.c.

119{
122 ULONG cbSize;
123
124 /* Make sure no image is loaded yet */
125 ASSERT(pldev && pldev->pGdiDriverInfo == NULL);
126
127 /* Allocate a SYSTEM_GDI_DRIVER_INFORMATION structure */
128 cbSize = sizeof(SYSTEM_GDI_DRIVER_INFORMATION) + pustrPathName->Length;
129 pDriverInfo = ExAllocatePoolWithTag(PagedPool, cbSize, GDITAG_LDEV);
130 if (!pDriverInfo)
131 {
132 ERR("Failed to allocate SYSTEM_GDI_DRIVER_INFORMATION\n");
133 return FALSE;
134 }
135
136 /* Initialize the UNICODE_STRING and copy the driver name */
137 RtlInitEmptyUnicodeString(&pDriverInfo->DriverName,
138 (PWSTR)(pDriverInfo + 1),
139 pustrPathName->Length);
140 RtlCopyUnicodeString(&pDriverInfo->DriverName, pustrPathName);
141
142 /* Try to load the driver */
144 pDriverInfo,
146 if (!NT_SUCCESS(Status))
147 {
148 ERR("Failed to load a GDI driver: '%wZ', Status = 0x%lx\n",
149 pustrPathName, Status);
150
151 /* Free the allocated memory */
152 ExFreePoolWithTag(pDriverInfo, GDITAG_LDEV);
153 return FALSE;
154 }
155
156 /* Set the driver info */
157 pldev->pGdiDriverInfo = pDriverInfo;
158
159 /* Return success. */
160 return TRUE;
161}
struct _SYSTEM_GDI_DRIVER_INFORMATION SYSTEM_GDI_DRIVER_INFORMATION
#define SystemLoadGdiDriverInformation
Definition: DriverTester.h:34
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:25
NTSYSAPI NTSTATUS NTAPI ZwSetSystemInformation(_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass, _In_reads_bytes_(SystemInformationLength) PVOID SystemInformation, _In_ ULONG SystemInformationLength)
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)

Referenced by LDEVOBJ_pLoadDriver().

◆ LDEVOBJ_bProbeAndCaptureDevmode()

BOOL LDEVOBJ_bProbeAndCaptureDevmode ( _Inout_ PGRAPHICS_DEVICE  pGraphicsDevice,
_In_ PDEVMODEW  RequestedMode,
_Out_ PDEVMODEW pSelectedMode,
_In_ BOOL  bSearchClosestMode 
)

Definition at line 735 of file ldevobj.c.

740{
741 DEVMODEW dmSearch;
742 PDEVMODEW pdmCurrent, pdm, pdmSelected = NULL;
743 ULONG i;
744 ULONG ulVirtualWidth = 0, ulVirtualHeight = 0;
745 BOOL bResult = TRUE;
747
748 if (!LDEVOBJ_bBuildDevmodeList(pGraphicsDevice))
749 return FALSE;
750
751 /* At first, load information from registry */
752 RtlZeroMemory(&dmSearch, sizeof(dmSearch));
753 Status = EngpGetDisplayDriverParameters(pGraphicsDevice, &dmSearch);
754 if (!NT_SUCCESS(Status))
755 {
756 ERR("EngpGetDisplayDriverParameters() failed with status 0x%08x\n", Status);
757 return FALSE;
758 }
759
760 /* Override values with the new ones provided */
761
763 {
764 bSearchClosestMode |= RequestedMode->dmFields == 0;
765
766 /* Copy standard fields (if provided) */
767 if (RequestedMode->dmFields & DM_BITSPERPEL && RequestedMode->dmBitsPerPel != 0)
768 dmSearch.dmBitsPerPel = RequestedMode->dmBitsPerPel;
769 if (RequestedMode->dmFields & DM_PELSWIDTH && RequestedMode->dmPelsWidth != 0)
770 dmSearch.dmPelsWidth = RequestedMode->dmPelsWidth;
771 if (RequestedMode->dmFields & DM_PELSHEIGHT && RequestedMode->dmPelsHeight != 0)
772 dmSearch.dmPelsHeight = RequestedMode->dmPelsHeight;
773 if (RequestedMode->dmFields & DM_DISPLAYFREQUENCY && RequestedMode->dmDisplayFrequency != 0)
774 dmSearch.dmDisplayFrequency = RequestedMode->dmDisplayFrequency;
775
776 if ((RequestedMode->dmFields & (DM_PANNINGWIDTH | DM_PANNINGHEIGHT)) == (DM_PANNINGWIDTH | DM_PANNINGHEIGHT) &&
777 RequestedMode->dmPanningWidth != 0 && RequestedMode->dmPanningHeight != 0 &&
778 RequestedMode->dmPanningWidth < dmSearch.dmPelsWidth &&
779 RequestedMode->dmPanningHeight < dmSearch.dmPelsHeight)
780 {
781 /* Get new panning values */
782 ulVirtualWidth = RequestedMode->dmPelsWidth;
783 ulVirtualHeight = RequestedMode->dmPelsHeight;
784 dmSearch.dmPelsWidth = RequestedMode->dmPanningWidth;
785 dmSearch.dmPelsHeight = RequestedMode->dmPanningHeight;
786 }
787 else if (dmSearch.dmPanningWidth != 0 && dmSearch.dmPanningHeight != 0 &&
788 dmSearch.dmPanningWidth < dmSearch.dmPelsWidth &&
789 dmSearch.dmPanningHeight < dmSearch.dmPelsHeight)
790 {
791 /* Keep existing panning values */
792 ulVirtualWidth = dmSearch.dmPelsWidth;
793 ulVirtualHeight = dmSearch.dmPelsHeight;
794 dmSearch.dmPelsWidth = dmSearch.dmPanningWidth;
795 dmSearch.dmPelsHeight = dmSearch.dmPanningHeight;
796 }
797 }
799 {
800 bResult = FALSE;
801 }
802 _SEH2_END;
803
804 if (!bResult)
805 return FALSE;
806
807 if (LDEVOBJ_bGetClosestMode(pGraphicsDevice, &dmSearch, &pdmSelected))
808 {
809 if (bSearchClosestMode)
810 {
811 /* Ok, found a closest mode. Update search */
812 dmSearch.dmBitsPerPel = pdmSelected->dmBitsPerPel;
813 dmSearch.dmPelsWidth = pdmSelected->dmPelsWidth;
814 dmSearch.dmPelsHeight = pdmSelected->dmPelsHeight;
815 dmSearch.dmDisplayFrequency = pdmSelected->dmDisplayFrequency;
816 }
817 else
818 {
819 /* Only update not provided fields */
821 {
822 if (!(RequestedMode->dmFields & DM_BITSPERPEL) || RequestedMode->dmBitsPerPel == 0)
823 dmSearch.dmBitsPerPel = pdmSelected->dmBitsPerPel;
824 if (!(RequestedMode->dmFields & DM_PELSWIDTH) || RequestedMode->dmPelsWidth == 0)
825 dmSearch.dmPelsWidth = pdmSelected->dmPelsWidth;
826 if (!(RequestedMode->dmFields & DM_PELSHEIGHT) || RequestedMode->dmPelsHeight == 0)
827 dmSearch.dmPelsHeight = pdmSelected->dmPelsHeight;
828 if (!(RequestedMode->dmFields & DM_DISPLAYFREQUENCY) || RequestedMode->dmDisplayFrequency == 0)
829 dmSearch.dmDisplayFrequency = pdmSelected->dmDisplayFrequency;
830 }
832 {
833 bResult = FALSE;
834 }
835 _SEH2_END;
836
837 if (!bResult)
838 return FALSE;
839 }
840 }
841
842 /* Now, search the exact mode to return to caller */
843 for (i = 0; i < pGraphicsDevice->cDevModes; i++)
844 {
845 pdmCurrent = pGraphicsDevice->pDevModeList[i].pdm;
846
847 /* For now, we only need those */
848 if (pdmCurrent->dmBitsPerPel != dmSearch.dmBitsPerPel)
849 continue;
850 if (pdmCurrent->dmPelsWidth != dmSearch.dmPelsWidth)
851 continue;
852 if (pdmCurrent->dmPelsHeight != dmSearch.dmPelsHeight)
853 continue;
854 if (pdmCurrent->dmDisplayFrequency != dmSearch.dmDisplayFrequency)
855 continue;
856
857 pdmSelected = pdmCurrent;
858 break;
859 }
860
861 if (!pdmSelected)
862 {
863 ERR("Requested mode not found (%dx%dx%d %d Hz)\n",
864 dmSearch.dmPelsWidth,
865 dmSearch.dmPelsHeight,
866 dmSearch.dmBitsPerPel,
867 dmSearch.dmDisplayFrequency);
868 return FALSE;
869 }
870
871 /* Allocate memory for output */
872 pdm = ExAllocatePoolZero(PagedPool, pdmSelected->dmSize + pdmSelected->dmDriverExtra, GDITAG_DEVMODE);
873 if (!pdm)
874 return FALSE;
875
876 /* Copy selected mode */
877 RtlCopyMemory(pdm, pdmSelected, pdmSelected->dmSize);
878 RtlCopyMemory((PVOID)((ULONG_PTR)pdm + pdm->dmSize),
879 (PVOID)((ULONG_PTR)pdmSelected + pdmSelected->dmSize),
880 pdmSelected->dmDriverExtra);
881
882 /* Add back panning */
883 if (ulVirtualWidth != 0 && ulVirtualHeight != 0 &&
884 pdm->dmPelsWidth < ulVirtualWidth &&
885 pdm->dmPelsHeight < ulVirtualHeight)
886 {
888 pdm->dmPanningWidth = pdm->dmPelsWidth;
889 pdm->dmPanningHeight = pdm->dmPelsHeight;
890 pdm->dmPelsWidth = ulVirtualWidth;
891 pdm->dmPelsHeight = ulVirtualHeight;
892 }
893
894 *pSelectedMode = pdm;
895 return TRUE;
896}
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned int BOOL
Definition: ntddk_ex.h:94
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
BOOL LDEVOBJ_bBuildDevmodeList(_Inout_ PGRAPHICS_DEVICE pGraphicsDevice)
Definition: ldevobj.c:563
static BOOL LDEVOBJ_bGetClosestMode(_Inout_ PGRAPHICS_DEVICE pGraphicsDevice, _In_ PDEVMODEW RequestedMode, _Out_ PDEVMODEW *pSelectedMode)
Definition: ldevobj.c:676
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
DWORD dmFields
Definition: wingdi.h:1622
uint32_t ULONG_PTR
Definition: typedefs.h:65
NTSTATUS EngpGetDisplayDriverParameters(_In_ PGRAPHICS_DEVICE pGraphicsDevice, _Out_ PDEVMODEW pdm)
Definition: device.c:354
#define DM_DISPLAYFREQUENCY
Definition: wingdi.h:1272
#define DM_PELSWIDTH
Definition: wingdi.h:1269
#define DM_PANNINGHEIGHT
Definition: wingdi.h:1278
#define DM_BITSPERPEL
Definition: wingdi.h:1268
#define DM_PELSHEIGHT
Definition: wingdi.h:1270
#define DM_PANNINGWIDTH
Definition: wingdi.h:1277

Referenced by MDEVOBJ_Create(), PDEVOBJ_lChangeDisplaySettings(), and UserChangeDisplaySettings().

◆ LDEVOBJ_bUnloadImage()

static BOOL LDEVOBJ_bUnloadImage ( _Inout_ PLDEVOBJ  pldev)
static

Definition at line 269 of file ldevobj.c.

271{
273
274 /* Make sure we have a driver info */
275 ASSERT(pldev && pldev->pGdiDriverInfo != NULL);
276 ASSERT(pldev->cRefs == 0);
277
278 TRACE("LDEVOBJ_bUnloadImage('%wZ')\n", &pldev->pGdiDriverInfo->DriverName);
279
280 /* Unload the driver */
281#if 0
283 &pldev->pGdiDriverInfo->SectionPointer,
284 sizeof(HANDLE));
285#else
286 /* Unfortunately, ntoskrnl allows unloading a driver, but fails loading
287 * it again with STATUS_IMAGE_ALREADY_LOADED. Prevent this problem by
288 * never unloading any driver.
289 */
292#endif
293 if (!NT_SUCCESS(Status))
294 return FALSE;
295
296 ExFreePoolWithTag(pldev->pGdiDriverInfo, GDITAG_LDEV);
297 pldev->pGdiDriverInfo = NULL;
298
299 return TRUE;
300}
#define UNIMPLEMENTED
Definition: debug.h:115
@ SystemUnloadGdiDriverInformation
Definition: ntddk_ex.h:38
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239

Referenced by LDEVOBJ_pLoadDriver(), and LDEVOBJ_vDereference().

◆ LDEVOBJ_pLoadDriver()

PLDEVOBJ NTAPI LDEVOBJ_pLoadDriver ( _In_z_ LPWSTR  pwszDriverName,
_In_ ULONG  ldevtype 
)

Definition at line 347 of file ldevobj.c.

350{
351 WCHAR acwBuffer[MAX_PATH];
352 PLIST_ENTRY pleLink;
353 PLDEVOBJ pldev;
354 UNICODE_STRING strDriverName;
355 SIZE_T cwcLength;
356 LPWSTR pwsz;
357
358 TRACE("LDEVOBJ_pLoadDriver(%ls, %lu)\n", pwszDriverName, ldevtype);
359 ASSERT(pwszDriverName);
360
361 /* Initialize buffer for the the driver name */
362 RtlInitEmptyUnicodeString(&strDriverName, acwBuffer, sizeof(acwBuffer));
363
364 /* Start path with systemroot */
365 RtlAppendUnicodeToString(&strDriverName, L"\\SystemRoot\\System32\\");
366
367 /* Get Length of given string */
368 cwcLength = wcslen(pwszDriverName);
369
370 /* Check if we have a system32 path given */
371 pwsz = pwszDriverName + cwcLength;
372 while (pwsz > pwszDriverName)
373 {
374 if ((*pwsz == L'\\') && (_wcsnicmp(pwsz, L"\\system32\\", 10) == 0))
375 {
376 /* Driver name starts after system32 */
377 pwsz += 10;
378 break;
379 }
380 pwsz--;
381 }
382
383 /* Append the driver name */
384 RtlAppendUnicodeToString(&strDriverName, pwsz);
385
386 /* MSDN says "The driver must include this suffix in the pwszDriver string."
387 But in fact it's optional. The function can also load .sys files without
388 appending the .dll extension. */
389 if ((cwcLength < 4) ||
390 ((_wcsnicmp(pwszDriverName + cwcLength - 4, L".dll", 4) != 0) &&
391 (_wcsnicmp(pwszDriverName + cwcLength - 4, L".sys", 4) != 0)) )
392 {
393 /* Append the .dll suffix */
394 RtlAppendUnicodeToString(&strDriverName, L".dll");
395 }
396
397 /* Lock loader */
399
400 /* Search the List of LDEVS for the driver name */
401 for (pleLink = gleLdevListHead.Flink;
402 pleLink != &gleLdevListHead;
403 pleLink = pleLink->Flink)
404 {
405 pldev = CONTAINING_RECORD(pleLink, LDEVOBJ, leLink);
406
407 /* Check if the ldev is associated with a file */
408 if (pldev->pGdiDriverInfo)
409 {
410 /* Check for match (case insensative) */
411 if (RtlEqualUnicodeString(&pldev->pGdiDriverInfo->DriverName, &strDriverName, TRUE))
412 {
413 /* Image found in LDEV list */
414 break;
415 }
416 }
417 }
418
419 /* Did we find one? */
420 if (pleLink == &gleLdevListHead)
421 {
422 /* No, allocate a new LDEVOBJ */
423 pldev = LDEVOBJ_AllocLDEV(ldevtype);
424 if (!pldev)
425 {
426 ERR("Could not allocate LDEV\n");
427 goto leave;
428 }
429
430 /* Load the image */
431 if (!LDEVOBJ_bLoadImage(pldev, &strDriverName))
432 {
433 LDEVOBJ_vFreeLDEV(pldev);
434 pldev = NULL;
435 ERR("LDEVOBJ_bLoadImage failed\n");
436 goto leave;
437 }
438
439 /* Load the driver */
441 {
442 ERR("LDEVOBJ_bEnableDriver failed\n");
443
444 /* Unload the image. */
446 LDEVOBJ_vFreeLDEV(pldev);
447 pldev = NULL;
448 goto leave;
449 }
450
451 /* Insert the LDEV into the global list */
453 }
454
455 /* Increase ref count */
456 pldev->cRefs++;
457
458leave:
459 /* Unlock loader */
461
462 TRACE("LDEVOBJ_pLoadDriver returning %p\n", pldev);
463 return pldev;
464}
#define leave
Definition: btrfs_drv.h:138
#define MAX_PATH
Definition: compat.h:34
#define InsertHeadList(ListHead, Entry)
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
VOID WINAPI EngReleaseSemaphore(IN HSEMAPHORE hsem)
Definition: eng.c:235
static BOOL LDEVOBJ_bLoadImage(_Inout_ PLDEVOBJ pldev, _In_ PUNICODE_STRING pustrPathName)
Definition: ldevobj.c:116
static PLDEVOBJ LDEVOBJ_AllocLDEV(_In_ LDEVTYPE ldevtype)
Definition: ldevobj.c:79
static VOID LDEVOBJ_vFreeLDEV(_In_ _Post_ptr_invalid_ PLDEVOBJ pldev)
Definition: ldevobj.c:103
static BOOL LDEVOBJ_bUnloadImage(_Inout_ PLDEVOBJ pldev)
Definition: ldevobj.c:269
static BOOL LDEVOBJ_bEnableDriver(_Inout_ PLDEVOBJ pldev, _In_ PFN_DrvEnableDriver pfnEnableDriver)
Definition: ldevobj.c:165
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
Definition: typedefs.h:120
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
ENGAPI VOID APIENTRY EngAcquireSemaphore(_Inout_ HSEMAPHORE hsem)
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by EngLoadImage(), LDEVOBJ_ulGetDriverModes(), and PDEVOBJ_Create().

◆ LDEVOBJ_pLoadInternal()

PLDEVOBJ LDEVOBJ_pLoadInternal ( _In_ PFN_DrvEnableDriver  pfnEnableDriver,
_In_ ULONG  ldevtype 
)

Definition at line 303 of file ldevobj.c.

306{
307 PLDEVOBJ pldev;
308
309 TRACE("LDEVOBJ_pLoadInternal(%lu)\n", ldevtype);
310
311 /* Lock loader */
313
314 /* Allocate a new LDEVOBJ */
315 pldev = LDEVOBJ_AllocLDEV(ldevtype);
316 if (!pldev)
317 {
318 ERR("Could not allocate LDEV\n");
319 goto leave;
320 }
321
322 /* Load the driver */
323 if (!LDEVOBJ_bEnableDriver(pldev, pfnEnableDriver))
324 {
325 ERR("LDEVOBJ_bEnableDriver failed\n");
326 LDEVOBJ_vFreeLDEV(pldev);
327 pldev = NULL;
328 goto leave;
329 }
330
331 /* Insert the LDEV into the global list */
333
334 /* Increase ref count */
335 pldev->cRefs++;
336
337leave:
338 /* Unlock loader */
340
341 TRACE("LDEVOBJ_pLoadInternal returning %p\n", pldev);
342 return pldev;
343}

Referenced by PDEVOBJ_Create().

◆ LDEVOBJ_pvFindImageProcAddress()

static PVOID LDEVOBJ_pvFindImageProcAddress ( _In_ PLDEVOBJ  pldev,
_In_z_ LPSTR  pszProcName 
)
static

Definition at line 223 of file ldevobj.c.

226{
227 PVOID pvImageBase;
228 PIMAGE_EXPORT_DIRECTORY pExportDir;
229 PVOID pvProcAdress = NULL;
230 PUSHORT pOrdinals;
231 PULONG pNames, pAddresses;
232 ULONG i;
233
234 /* Make sure we have a driver info */
235 ASSERT(pldev && pldev->pGdiDriverInfo != NULL);
236
237 /* Get the pointer to the export directory */
238 pvImageBase = pldev->pGdiDriverInfo->ImageAddress;
239 pExportDir = pldev->pGdiDriverInfo->ExportSectionPointer;
240 if (!pExportDir)
241 {
242 ERR("LDEVOBJ_pvFindImageProcAddress: no export section found\n");
243 return NULL;
244 }
245
246 /* Get pointers to some tables */
247 pNames = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfNames);
248 pOrdinals = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfNameOrdinals);
249 pAddresses = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfFunctions);
250
251 /* Loop the export table */
252 for (i = 0; i < pExportDir->NumberOfNames; i++)
253 {
254 /* Compare the name */
255 if (_stricmp(pszProcName, RVA_TO_ADDR(pvImageBase, pNames[i])) == 0)
256 {
257 /* Found! Calculate the procedure address */
258 pvProcAdress = RVA_TO_ADDR(pvImageBase, pAddresses[pOrdinals[i]]);
259 break;
260 }
261 }
262
263 /* Return the address */
264 return pvProcAdress;
265}
#define _stricmp
Definition: cat.c:22
#define RVA_TO_ADDR(Base, Rva)
Definition: ldevobj.c:15
DWORD AddressOfNameOrdinals
Definition: compat.h:167
uint32_t * PULONG
Definition: typedefs.h:59
uint16_t * PUSHORT
Definition: typedefs.h:56

Referenced by EngFindImageProcAddress().

◆ LDEVOBJ_ulGetDriverModes()

ULONG LDEVOBJ_ulGetDriverModes ( _In_ LPWSTR  pwszDriverName,
_In_ HANDLE  hDriver,
_Out_ PDEVMODEW ppdm 
)

Definition at line 509 of file ldevobj.c.

513{
514 PLDEVOBJ pldev = NULL;
515 ULONG cbSize = 0;
516 PDEVMODEW pdm = NULL;
517
518 TRACE("LDEVOBJ_ulGetDriverModes('%ls', %p)\n", pwszDriverName, hDriver);
519
520 pldev = LDEVOBJ_pLoadDriver(pwszDriverName, LDEV_DEVICE_DISPLAY);
521 if (!pldev)
522 goto cleanup;
523
524 /* Mirror drivers may omit this function */
525 if (!pldev->pfn.GetModes)
526 goto cleanup;
527
528 /* Call the driver to get the required size */
529 cbSize = pldev->pfn.GetModes(hDriver, 0, NULL);
530 if (!cbSize)
531 {
532 ERR("DrvGetModes returned 0\n");
533 goto cleanup;
534 }
535
536 /* Allocate a buffer for the DEVMODE array */
538 if (!pdm)
539 {
540 ERR("Could not allocate devmodeinfo\n");
541 goto cleanup;
542 }
543
544 /* Call the driver again to fill the buffer */
545 cbSize = pldev->pfn.GetModes(hDriver, cbSize, pdm);
546 if (!cbSize)
547 {
548 /* Could not get modes */
549 ERR("DrvrGetModes returned 0 on second call\n");
551 pdm = NULL;
552 }
553
554cleanup:
555 if (pldev)
557
558 *ppdm = pdm;
559 return cbSize;
560}
static void cleanup(void)
Definition: main.c:1335
PFN_DrvGetModes GetModes
Definition: ntgdityp.h:610
DRIVER_FUNCTIONS pfn
Definition: ldevobj.h:27
_In_ LPWSTR _In_ ULONG _In_ ULONG _In_ ULONG _Out_ DEVINFO _In_ HDEV _In_ LPWSTR _In_ HANDLE hDriver
Definition: winddi.h:3557

Referenced by LDEVOBJ_bBuildDevmodeList().

◆ LDEVOBJ_vDereference()

static VOID LDEVOBJ_vDereference ( _Inout_ PLDEVOBJ  pldev)
static

Definition at line 468 of file ldevobj.c.

470{
471 /* Lock loader */
473
474 /* Decrement reference count */
475 ASSERT(pldev->cRefs > 0);
476 pldev->cRefs--;
477
478 /* More references left? */
479 if (pldev->cRefs > 0)
480 {
482 return;
483 }
484
486
487 if (LDEVOBJ_bUnloadImage(pldev))
488 {
489 /* Remove ldev from the list */
490 RemoveEntryList(&pldev->leLink);
491
492 /* Free the driver info structure */
493 LDEVOBJ_vFreeLDEV(pldev);
494 }
495 else
496 {
497 WARN("Failed to unload driver '%wZ', trying to re-enable it.\n", &pldev->pGdiDriverInfo->DriverName);
498 LDEVOBJ_bEnableDriver(pldev, pldev->pGdiDriverInfo->EntryPoint);
499
500 /* Increment again reference count */
501 pldev->cRefs++;
502 }
503
504 /* Unlock loader */
506}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
static VOID LDEVOBJ_vDisableDriver(_Inout_ PLDEVOBJ pldev)
Definition: ldevobj.c:203

Referenced by EngUnloadImage(), and LDEVOBJ_ulGetDriverModes().

◆ LDEVOBJ_vDisableDriver()

static VOID LDEVOBJ_vDisableDriver ( _Inout_ PLDEVOBJ  pldev)
static

Definition at line 203 of file ldevobj.c.

205{
206 ASSERT(pldev);
207 ASSERT(pldev->cRefs == 0);
208
209 TRACE("LDEVOBJ_vDisableDriver('%wZ')\n", &pldev->pGdiDriverInfo->DriverName);
210
211 if (pldev->ldevtype == LDEV_IMAGE)
212 return;
213
214 if (pldev->pfn.DisableDriver)
215 {
216 /* Call the unload function */
217 pldev->pfn.DisableDriver();
218 }
219}

Referenced by LDEVOBJ_vDereference().

◆ LDEVOBJ_vFreeLDEV()

static VOID LDEVOBJ_vFreeLDEV ( _In_ _Post_ptr_invalid_ PLDEVOBJ  pldev)
static

Definition at line 103 of file ldevobj.c.

105{
106 /* Make sure we don't have a driver loaded */
107 ASSERT(pldev && pldev->pGdiDriverInfo == NULL);
108 ASSERT(pldev->cRefs == 0);
109
110 /* Free the memory */
112}

Referenced by LDEVOBJ_pLoadDriver(), LDEVOBJ_pLoadInternal(), and LDEVOBJ_vDereference().

Variable Documentation

◆ ghsemLDEVList

HSEMAPHORE ghsemLDEVList
static

Globals

Definition at line 20 of file ldevobj.c.

Referenced by InitLDEVImpl(), LDEVOBJ_pLoadDriver(), LDEVOBJ_pLoadInternal(), and LDEVOBJ_vDereference().

◆ gleLdevListHead

LIST_ENTRY gleLdevListHead
static

Definition at line 21 of file ldevobj.c.

Referenced by InitLDEVImpl(), LDEVOBJ_pLoadDriver(), and LDEVOBJ_pLoadInternal().

◆ gpldevWin32k

LDEVOBJ* gpldevWin32k = NULL
static

Definition at line 22 of file ldevobj.c.

Referenced by EngFindImageProcAddress(), and InitLDEVImpl().