ReactOS  0.4.13-dev-249-gcba1a2f
icdload.c File Reference
#include "opengl32.h"
#include <winreg.h>
Include dependency graph for icdload.c:

Go to the source code of this file.

Classes

struct  Drv_Opengl_Info
 

Macros

#define DRV_LOAD(x)
 

Typedefs

typedef struct Drv_Opengl_InfopDrv_Opengl_Info
 

Enumerations

enum  CUSTOM_DRIVER_STATE { OGL_CD_NOT_QUERIED, OGL_CD_NONE, OGL_CD_ROSSWI, OGL_CD_CUSTOM_ICD }
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (opengl32)
 
static void APIENTRY wglSetCurrentValue (PVOID value)
 
static PVOID APIENTRY wglGetCurrentValue ()
 
static DHGLRC APIENTRY wglGetDHGLRC (struct wgl_context *context)
 
INT APIENTRY GdiDescribePixelFormat (HDC hdc, INT ipfd, UINT cjpfd, PPIXELFORMATDESCRIPTOR ppfd)
 
BOOL APIENTRY GdiSetPixelFormat (HDC hdc, INT ipfd)
 
BOOL APIENTRY GdiSwapBuffers (HDC hdc)
 
struct ICD_DataIntGetIcdData (HDC hdc)
 
void IntDeleteAllICDs (void)
 

Variables

static CRITICAL_SECTION icdload_cs = {NULL, -1, 0, 0, 0, 0}
 
static struct ICD_DataICD_Data_List = NULL
 
static const WCHAR OpenGLDrivers_Key [] = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers"
 
static const WCHAR CustomDrivers_Key [] = L"SOFTWARE\\ReactOS\\OpenGL"
 
static Drv_Opengl_Info CustomDrvInfo
 
static CUSTOM_DRIVER_STATE CustomDriverState = OGL_CD_NOT_QUERIED
 

Macro Definition Documentation

◆ DRV_LOAD

#define DRV_LOAD (   x)
Value:
do \
{ \
data->x = (void*)GetProcAddress(data->hModule, #x); \
if(!data->x) { \
ERR("%S lacks " #x "!\n", DllName); \
goto fail; \
} \
} while(0)
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define GetProcAddress(x, y)
Definition: compat.h:410

Typedef Documentation

◆ pDrv_Opengl_Info

Enumeration Type Documentation

◆ CUSTOM_DRIVER_STATE

Enumerator
OGL_CD_NOT_QUERIED 
OGL_CD_NONE 
OGL_CD_ROSSWI 
OGL_CD_CUSTOM_ICD 

Definition at line 21 of file icdload.c.

Function Documentation

◆ GdiDescribePixelFormat()

INT APIENTRY GdiDescribePixelFormat ( HDC  hdc,
INT  ipfd,
UINT  cjpfd,
PPIXELFORMATDESCRIPTOR  ppfd 
)

Referenced by IntGetIcdData().

◆ GdiSetPixelFormat()

BOOL APIENTRY GdiSetPixelFormat ( HDC  hdc,
INT  ipfd 
)

Referenced by IntGetIcdData().

◆ GdiSwapBuffers()

BOOL APIENTRY GdiSwapBuffers ( HDC  hdc)

Referenced by IntGetIcdData().

◆ IntDeleteAllICDs()

void IntDeleteAllICDs ( void  )

Definition at line 357 of file icdload.c.

358 {
359  struct ICD_Data* data;
360 
362 
363  while (ICD_Data_List != NULL)
364  {
366  ICD_Data_List = data->next;
367 
368  FreeLibrary(data->hModule);
370  }
371 }
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
static CRITICAL_SECTION icdload_cs
Definition: icdload.c:29
smooth NULL
Definition: ftsmooth.c:416
static struct ICD_Data * ICD_Data_List
Definition: icdload.c:30
#define FreeLibrary(x)
Definition: compat.h:405
#define GetProcessHeap()
Definition: compat.h:395
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
Definition: icd.h:365
#define HeapFree(x, y, z)
Definition: compat.h:394

Referenced by DllMain().

◆ IntGetIcdData()

struct ICD_Data* IntGetIcdData ( HDC  hdc)

Definition at line 57 of file icdload.c.

58 {
59  int ret;
60  DWORD dwInput, dwValueType, Version, DriverVersion, Flags;
61  Drv_Opengl_Info DrvInfo;
62  pDrv_Opengl_Info pDrvInfo;
63  struct ICD_Data* data;
64  HKEY OglKey = NULL;
65  HKEY DrvKey, CustomKey;
66  WCHAR DllName[MAX_PATH];
67  BOOL (WINAPI *DrvValidateVersion)(DWORD);
68  void (WINAPI *DrvSetCallbackProcs)(int nProcs, PROC* pProcs);
69 
70  /* The following code is ReactOS specific and allows us to easily load an arbitrary ICD:
71  * It checks HKCU\Software\ReactOS\OpenGL for a custom ICD and will always load it
72  * no matter what driver the DC is associated with. It can also force using the
73  * built-in Software Implementation*/
75  {
76  /* Only do this once so there's not any significant performance penalty */
78  memset(&CustomDrvInfo, 0, sizeof(Drv_Opengl_Info));
79 
81  if(ret != ERROR_SUCCESS)
82  goto custom_end;
83 
84  dwInput = sizeof(CustomDrvInfo.DriverName);
85  ret = RegQueryValueExW(CustomKey, L"", 0, &dwValueType, (LPBYTE)CustomDrvInfo.DriverName, &dwInput);
86  RegCloseKey(CustomKey);
87 
88  if((ret != ERROR_SUCCESS) || (dwValueType != REG_SZ) || !wcslen(CustomDrvInfo.DriverName))
89  goto custom_end;
90 
91  if(!_wcsicmp(CustomDrvInfo.DriverName, L"ReactOS Software Implementation"))
92  {
93  /* Always announce the fact that we're forcing ROSSWI */
94  ERR("Forcing ReactOS Software Implementation\n");
96  return NULL;
97  }
98 
100  if(ret != ERROR_SUCCESS)
101  goto custom_end;
102 
103  ret = RegOpenKeyExW(OglKey, CustomDrvInfo.DriverName, 0, KEY_READ, &OglKey);
104  if(ret != ERROR_SUCCESS)
105  goto custom_end;
106 
107  dwInput = sizeof(CustomDrvInfo.Version);
108  ret = RegQueryValueExW(OglKey, L"Version", 0, &dwValueType, (LPBYTE)&CustomDrvInfo.Version, &dwInput);
109  if((ret != ERROR_SUCCESS) || (dwValueType != REG_DWORD))
110  goto custom_end;
111 
112  dwInput = sizeof(DriverVersion);
113  ret = RegQueryValueExW(OglKey, L"DriverVersion", 0, &dwValueType, (LPBYTE)&CustomDrvInfo.DriverVersion, &dwInput);
115 
116  /* Always announce the fact that we're overriding the default driver */
117  ERR("Overriding the default OGL ICD with %S\n", CustomDrvInfo.DriverName);
118 
119 custom_end:
120  if(OglKey)
121  RegCloseKey(OglKey);
122  RegCloseKey(CustomKey);
123  }
124 
125  /* If there's a custom ICD or ROSSWI was requested use it, otherwise proceed as usual */
127  {
128  pDrvInfo = &CustomDrvInfo;
129  }
130  else if(CustomDriverState == OGL_CD_ROSSWI)
131  {
132  return NULL;
133  }
134  else
135  {
136  /* First, see if the driver supports this */
137  dwInput = OPENGL_GETINFO;
138  ret = ExtEscape(hdc, QUERYESCSUPPORT, sizeof(DWORD), (LPCSTR)&dwInput, 0, NULL);
139 
140  /* Driver doesn't support opengl */
141  if(ret <= 0)
142  return NULL;
143 
144  /* Query for the ICD DLL name and version */
145  dwInput = 0;
146  ret = ExtEscape(hdc, OPENGL_GETINFO, sizeof(DWORD), (LPCSTR)&dwInput, sizeof(DrvInfo), (LPSTR)&DrvInfo);
147 
148  if(ret <= 0)
149  {
150  ERR("Driver claims to support OPENGL_GETINFO escape code, but doesn't.\n");
151  return NULL;
152  }
153 
154  pDrvInfo = &DrvInfo;
155  }
156 
157  /* Protect the list while we are loading*/
159 
160  /* Search for it in the list of already loaded modules */
162  while(data)
163  {
164  if(!_wcsicmp(data->DriverName, pDrvInfo->DriverName))
165  {
166  /* Found it */
167  TRACE("Found already loaded %p.\n", data);
169  return data;
170  }
171  data = data->next;
172  }
173 
174  /* It was still not loaded, look for it in the registry */
176  if(ret != ERROR_SUCCESS)
177  {
178  ERR("Failed to open the OpenGLDrivers key.\n");
179  goto end;
180  }
181  ret = RegOpenKeyExW(OglKey, pDrvInfo->DriverName, 0, KEY_READ, &DrvKey);
182  if(ret != ERROR_SUCCESS)
183  {
184  /* Some driver installer just provide the DLL name, like the Matrox G400 */
185  TRACE("No driver subkey for %S, trying to get DLL name directly.\n", pDrvInfo->DriverName);
186  dwInput = sizeof(DllName);
187  ret = RegQueryValueExW(OglKey, pDrvInfo->DriverName, 0, &dwValueType, (LPBYTE)DllName, &dwInput);
188  if((ret != ERROR_SUCCESS) || (dwValueType != REG_SZ))
189  {
190  ERR("Unable to get ICD DLL name!\n");
191  RegCloseKey(OglKey);
192  goto end;
193  }
194  Version = DriverVersion = Flags = 0;
195  TRACE("DLL name is %S.\n", DllName);
196  }
197  else
198  {
199  /* The driver have a subkey for the ICD */
200  TRACE("Querying details from registry for %S.\n", pDrvInfo->DriverName);
201  dwInput = sizeof(DllName);
202  ret = RegQueryValueExW(DrvKey, L"Dll", 0, &dwValueType, (LPBYTE)DllName, &dwInput);
203  if((ret != ERROR_SUCCESS) || (dwValueType != REG_SZ))
204  {
205  ERR("Unable to get ICD DLL name!.\n");
206  RegCloseKey(DrvKey);
207  RegCloseKey(OglKey);
208  goto end;
209  }
210 
211  dwInput = sizeof(Version);
212  ret = RegQueryValueExW(DrvKey, L"Version", 0, &dwValueType, (LPBYTE)&Version, &dwInput);
213  if((ret != ERROR_SUCCESS) || (dwValueType != REG_DWORD))
214  {
215  WARN("No version in driver subkey\n");
216  }
217  else if(Version != pDrvInfo->Version)
218  {
219  ERR("Version mismatch between registry (%lu) and display driver (%lu).\n", Version, pDrvInfo->Version);
220  RegCloseKey(DrvKey);
221  RegCloseKey(OglKey);
222  goto end;
223  }
224 
225  dwInput = sizeof(DriverVersion);
226  ret = RegQueryValueExW(DrvKey, L"DriverVersion", 0, &dwValueType, (LPBYTE)&DriverVersion, &dwInput);
227  if((ret != ERROR_SUCCESS) || (dwValueType != REG_DWORD))
228  {
229  WARN("No driver version in driver subkey\n");
230  }
231  else if(DriverVersion != pDrvInfo->DriverVersion)
232  {
233  ERR("Driver version mismatch between registry (%lu) and display driver (%lu).\n", DriverVersion, pDrvInfo->DriverVersion);
234  RegCloseKey(DrvKey);
235  RegCloseKey(OglKey);
236  goto end;
237  }
238 
239  dwInput = sizeof(Flags);
240  ret = RegQueryValueExW(DrvKey, L"Flags", 0, &dwValueType, (LPBYTE)&Flags, &dwInput);
241  if((ret != ERROR_SUCCESS) || (dwValueType != REG_DWORD))
242  {
243  WARN("No driver version in driver subkey\n");
244  Flags = 0;
245  }
246 
247  /* We're done */
248  RegCloseKey(DrvKey);
249  TRACE("DLL name is %S, Version %lx, DriverVersion %lx, Flags %lx.\n", DllName, Version, DriverVersion, Flags);
250  }
251  /* No need for this anymore */
252  RegCloseKey(OglKey);
253 
254  /* So far so good, allocate data */
255  data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data));
256  if(!data)
257  {
258  ERR("Unable to allocate ICD data!\n");
259  goto end;
260  }
261 
262  /* Load the library */
263  data->hModule = LoadLibraryW(DllName);
264  if(!data->hModule)
265  {
266  ERR("Could not load the ICD DLL: %S.\n", DllName);
268  data = NULL;
269  goto end;
270  }
271 
272  /*
273  * Validate version, if needed.
274  * Some drivers (at least VBOX), initialize stuff upon this call.
275  */
276  DrvValidateVersion = (void*)GetProcAddress(data->hModule, "DrvValidateVersion");
277  if(DrvValidateVersion)
278  {
279  if(!DrvValidateVersion(pDrvInfo->DriverVersion))
280  {
281  ERR("DrvValidateVersion failed!.\n");
282  goto fail;
283  }
284  }
285 
286  /* Pass the callbacks */
287  DrvSetCallbackProcs = (void*)GetProcAddress(data->hModule, "DrvSetCallbackProcs");
288  if(DrvSetCallbackProcs)
289  {
290  PROC callbacks[] = {
293  (PROC)wglGetDHGLRC};
294  DrvSetCallbackProcs(ARRAYSIZE(callbacks), callbacks);
295  }
296 
297  /* Get the DLL exports */
298 #define DRV_LOAD(x) do \
299 { \
300  data->x = (void*)GetProcAddress(data->hModule, #x); \
301  if(!data->x) { \
302  ERR("%S lacks " #x "!\n", DllName); \
303  goto fail; \
304  } \
305 } while(0)
306  DRV_LOAD(DrvCopyContext);
307  DRV_LOAD(DrvCreateContext);
308  DRV_LOAD(DrvCreateLayerContext);
309  DRV_LOAD(DrvDeleteContext);
310  DRV_LOAD(DrvDescribeLayerPlane);
312  DRV_LOAD(DrvGetLayerPaletteEntries);
313  DRV_LOAD(DrvGetProcAddress);
314  DRV_LOAD(DrvReleaseContext);
315  DRV_LOAD(DrvRealizeLayerPalette);
317  DRV_LOAD(DrvSetLayerPaletteEntries);
319  DRV_LOAD(DrvShareLists);
321  DRV_LOAD(DrvSwapLayerBuffers);
322 #undef DRV_LOAD
323 
324  /* Let's see if GDI should handle this instead of the ICD DLL */
325  // FIXME: maybe there is a better way
326  if (GdiDescribePixelFormat(hdc, 0, 0, NULL) != 0)
327  {
328  /* GDI knows what to do with that. Override */
329  TRACE("Forwarding WGL calls to win32k!\n");
330  data->DrvDescribePixelFormat = GdiDescribePixelFormat;
331  data->DrvSetPixelFormat = GdiSetPixelFormat;
332  data->DrvSwapBuffers = GdiSwapBuffers;
333  }
334 
335  /* Copy the DriverName */
336  wcscpy(data->DriverName, pDrvInfo->DriverName);
337 
338  /* Push the list */
339  data->next = ICD_Data_List;
341 
342  TRACE("Returning %p.\n", data);
343  TRACE("ICD driver %S (%S) successfully loaded.\n", pDrvInfo->DriverName, DllName);
344 
345 end:
346  /* Unlock and return */
348  return data;
349 
350 fail:
352  FreeLibrary(data->hModule);
354  return NULL;
355 }
static CUSTOM_DRIVER_STATE CustomDriverState
Definition: icdload.c:34
IN PVOID IN PVOID IN USHORT Version
Definition: pci.h:359
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define ERROR_SUCCESS
Definition: deptool.c:10
#define KEY_READ
Definition: nt_native.h:1023
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define WARN(fmt,...)
Definition: debug.h:111
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
GLuint GLuint end
Definition: gl.h:1545
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
char * LPSTR
Definition: xmlstorage.h:182
#define BOOL
Definition: nt_native.h:43
#define DWORD
Definition: nt_native.h:44
static DHGLRC APIENTRY wglGetDHGLRC(struct wgl_context *context)
Definition: icdload.c:46
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
static void APIENTRY wglSetCurrentValue(PVOID value)
Definition: icdload.c:36
unsigned char * LPBYTE
Definition: typedefs.h:52
FN_DrvDescribePixelFormat DrvDescribePixelFormat
static PVOID APIENTRY wglGetCurrentValue()
Definition: icdload.c:41
static CRITICAL_SECTION icdload_cs
Definition: icdload.c:29
#define LoadLibraryW(x)
Definition: compat.h:404
smooth NULL
Definition: ftsmooth.c:416
static struct ICD_Data * ICD_Data_List
Definition: icdload.c:30
#define DRV_LOAD(x)
DWORD Version
Definition: icdload.c:16
const char * LPCSTR
Definition: xmlstorage.h:183
#define TRACE(s)
Definition: solgame.cpp:4
#define FreeLibrary(x)
Definition: compat.h:405
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4134
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
BOOL APIENTRY GdiSwapBuffers(HDC hdc)
FN_DrvSwapBuffers DrvSwapBuffers
int ret
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
HDC hdc
Definition: main.c:9
#define QUERYESCSUPPORT
Definition: wingdi.h:990
static const WCHAR CustomDrivers_Key[]
Definition: icdload.c:32
#define ERR(fmt,...)
Definition: debug.h:109
DWORD DriverVersion
Definition: icdload.c:17
#define OPENGL_GETINFO
Definition: winddi.h:150
Definition: icd.h:365
WCHAR DriverName[256]
Definition: icdload.c:18
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3381
INT_PTR(WINAPI * PROC)()
Definition: windef.h:250
#define GetProcAddress(x, y)
Definition: compat.h:410
INT APIENTRY GdiDescribePixelFormat(HDC hdc, INT ipfd, UINT cjpfd, PPIXELFORMATDESCRIPTOR ppfd)
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
const GLCLTPROCTABLE *WINAPI * DrvSetContext(HDC hdc, DHGLRC hglrc, PFN_SETPROCTABLE callback)
static int callbacks
Definition: xmllint.c:873
#define memset(x, y, z)
Definition: compat.h:39
#define REG_DWORD
Definition: sdbapi.c:596
static Drv_Opengl_Info CustomDrvInfo
Definition: icdload.c:33
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:394
FN_DrvSetPixelFormat DrvSetPixelFormat
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
int WINAPI ExtEscape(_In_ HDC hdc, _In_ int iEscape, _In_ int cjInput, _In_reads_bytes_opt_(cjInput) LPCSTR lpInData, _In_ int cjOutput, _Out_writes_bytes_opt_(cjOutput) LPSTR lpOutData)
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
static const WCHAR OpenGLDrivers_Key[]
Definition: icdload.c:31
#define REG_SZ
Definition: layer.c:22
BOOL APIENTRY GdiSetPixelFormat(HDC hdc, INT ipfd)

Referenced by get_dc_data_ex(), and wglDescribePixelFormat().

◆ wglGetCurrentValue()

static PVOID APIENTRY wglGetCurrentValue ( )
static

Definition at line 41 of file icdload.c.

42 {
43  return IntGetCurrentICDPrivate();
44 }
FORCEINLINE void * IntGetCurrentICDPrivate(void)
Definition: opengl32.h:170

Referenced by IntGetIcdData().

◆ wglGetDHGLRC()

static DHGLRC APIENTRY wglGetDHGLRC ( struct wgl_context context)
static

Definition at line 46 of file icdload.c.

47 {
48  return context->dhglrc;
49 }
Definition: http.c:6587

Referenced by IntGetIcdData().

◆ wglSetCurrentValue()

static void APIENTRY wglSetCurrentValue ( PVOID  value)
static

Definition at line 36 of file icdload.c.

37 {
39 }
FORCEINLINE void IntSetCurrentICDPrivate(void *value)
Definition: opengl32.h:163

Referenced by IntGetIcdData().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( opengl32  )

Variable Documentation

◆ CustomDrivers_Key

const WCHAR CustomDrivers_Key[] = L"SOFTWARE\\ReactOS\\OpenGL"
static

Definition at line 32 of file icdload.c.

Referenced by IntGetIcdData().

◆ CustomDriverState

CUSTOM_DRIVER_STATE CustomDriverState = OGL_CD_NOT_QUERIED
static

Definition at line 34 of file icdload.c.

Referenced by IntGetIcdData().

◆ CustomDrvInfo

Drv_Opengl_Info CustomDrvInfo
static

Definition at line 33 of file icdload.c.

Referenced by IntGetIcdData().

◆ ICD_Data_List

struct ICD_Data* ICD_Data_List = NULL
static

Definition at line 30 of file icdload.c.

Referenced by IntDeleteAllICDs(), and IntGetIcdData().

◆ icdload_cs

CRITICAL_SECTION icdload_cs = {NULL, -1, 0, 0, 0, 0}
static

Definition at line 29 of file icdload.c.

Referenced by IntDeleteAllICDs(), and IntGetIcdData().

◆ OpenGLDrivers_Key

const WCHAR OpenGLDrivers_Key[] = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers"
static

Definition at line 31 of file icdload.c.

Referenced by IntGetIcdData().