ReactOS  0.4.13-dev-464-g6b95727
main.c
Go to the documentation of this file.
1 /* DirectDraw Base Functions
2  *
3  * Copyright 1997-1999 Marcus Meissner
4  * Copyright 1998 Lionel Ulmer
5  * Copyright 2000-2001 TransGaming Technologies Inc.
6  * Copyright 2006 Stefan Dösinger
7  * Copyright 2008 Denver Gingerich
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include "config.h"
25 #include "wine/port.h"
26 
27 #define DDRAW_INIT_GUID
28 #include "ddraw_private.h"
29 #include "rpcproxy.h"
30 
31 #include "wine/exception.h"
32 #include "winreg.h"
33 
35 
37 
39 
40 /* value of ForceRefreshRate */
42 
43 /* Structure for converting DirectDrawEnumerateA to DirectDrawEnumerateExA */
45 {
46  LPDDENUMCALLBACKA callback;
47  void *context;
48 };
49 
50 /* Enumeration callback for converting DirectDrawEnumerateA to DirectDrawEnumerateExA */
51 static BOOL CALLBACK enum_callback(GUID *guid, char *description, char *driver_name,
52  void *context, HMONITOR monitor)
53 {
54  const struct callback_info *info = context;
55 
56  return info->callback(guid, description, driver_name, info->context);
57 }
58 
59 static void ddraw_enumerate_secondary_devices(struct wined3d *wined3d, LPDDENUMCALLBACKEXA callback,
60  void *context)
61 {
62  struct wined3d_adapter_identifier adapter_id;
63  struct wined3d_output_desc output_desc;
64  BOOL cont_enum = TRUE;
65  HRESULT hr = S_OK;
66  UINT adapter = 0;
67 
68  for (adapter = 0; SUCCEEDED(hr) && cont_enum; adapter++)
69  {
70  char DriverName[512] = "", DriverDescription[512] = "";
71 
72  /* The Battle.net System Checker expects the GetAdapterIdentifier DeviceName to match the
73  * Driver Name, so obtain the DeviceName and GUID from D3D. */
74  memset(&adapter_id, 0x0, sizeof(adapter_id));
75  adapter_id.device_name = DriverName;
76  adapter_id.device_name_size = sizeof(DriverName);
77  adapter_id.description = DriverDescription;
78  adapter_id.description_size = sizeof(DriverDescription);
80  if (SUCCEEDED(hr = wined3d_get_adapter_identifier(wined3d, adapter, 0x0, &adapter_id)))
81  hr = wined3d_get_output_desc(wined3d, adapter, &output_desc);
83  if (SUCCEEDED(hr))
84  {
85  TRACE("Interface %d: %s\n", adapter, wine_dbgstr_guid(&adapter_id.device_identifier));
86  cont_enum = callback(&adapter_id.device_identifier, adapter_id.description,
87  adapter_id.device_name, context, output_desc.monitor);
88  }
89  }
90 }
91 
92 /* Handle table functions */
94 {
95  if (!(t->entries = heap_alloc_zero(initial_size * sizeof(*t->entries))))
96  {
97  ERR("Failed to allocate handle table memory.\n");
98  return FALSE;
99  }
100  t->free_entries = NULL;
101  t->table_size = initial_size;
102  t->entry_count = 0;
103 
104  return TRUE;
105 }
106 
108 {
109  heap_free(t->entries);
110  memset(t, 0, sizeof(*t));
111 }
112 
114 {
115  struct ddraw_handle_entry *entry;
116 
117  if (t->free_entries)
118  {
119  DWORD idx = t->free_entries - t->entries;
120  /* Use a free handle */
121  entry = t->free_entries;
122  if (entry->type != DDRAW_HANDLE_FREE)
123  {
124  ERR("Handle %#x (%p) is in the free list, but has type %#x.\n", idx, entry->object, entry->type);
125  return DDRAW_INVALID_HANDLE;
126  }
127  t->free_entries = entry->object;
128  entry->object = object;
129  entry->type = type;
130 
131  return idx;
132  }
133 
134  if (!(t->entry_count < t->table_size))
135  {
136  /* Grow the table */
137  UINT new_size = t->table_size + (t->table_size >> 1);
138  struct ddraw_handle_entry *new_entries;
139 
140  if (!(new_entries = heap_realloc(t->entries, new_size * sizeof(*t->entries))))
141  {
142  ERR("Failed to grow the handle table.\n");
143  return DDRAW_INVALID_HANDLE;
144  }
145  t->entries = new_entries;
146  t->table_size = new_size;
147  }
148 
149  entry = &t->entries[t->entry_count];
150  entry->object = object;
151  entry->type = type;
152 
153  return t->entry_count++;
154 }
155 
157 {
158  struct ddraw_handle_entry *entry;
159  void *object;
160 
161  if (handle == DDRAW_INVALID_HANDLE || handle >= t->entry_count)
162  {
163  WARN("Invalid handle %#x passed.\n", handle);
164  return NULL;
165  }
166 
167  entry = &t->entries[handle];
168  if (entry->type != type)
169  {
170  WARN("Handle %#x (%p) is not of type %#x.\n", handle, entry->object, type);
171  return NULL;
172  }
173 
174  object = entry->object;
175  entry->object = t->free_entries;
176  entry->type = DDRAW_HANDLE_FREE;
177  t->free_entries = entry;
178 
179  return object;
180 }
181 
183 {
184  struct ddraw_handle_entry *entry;
185 
186  if (handle == DDRAW_INVALID_HANDLE || handle >= t->entry_count)
187  {
188  WARN("Invalid handle %#x passed.\n", handle);
189  return NULL;
190  }
191 
192  entry = &t->entries[handle];
193  if (entry->type != type)
194  {
195  WARN("Handle %#x (%p) is not of type %#x.\n", handle, entry->object, type);
196  return NULL;
197  }
198 
199  return entry->object;
200 }
201 
202 HRESULT WINAPI GetSurfaceFromDC(HDC dc, IDirectDrawSurface4 **surface, HDC *device_dc)
203 {
204  struct ddraw *ddraw;
205 
206  TRACE("dc %p, surface %p, device_dc %p.\n", dc, surface, device_dc);
207 
208  if (!surface)
209  return E_INVALIDARG;
210 
211  if (!device_dc)
212  {
213  *surface = NULL;
214 
215  return E_INVALIDARG;
216  }
217 
220  {
221  if (FAILED(IDirectDraw4_GetSurfaceFromDC(&ddraw->IDirectDraw4_iface, dc, surface)))
222  continue;
223 
224  *device_dc = NULL; /* FIXME */
226  return DD_OK;
227  }
229 
230  *surface = NULL;
231  *device_dc = NULL;
232 
233  return DDERR_NOTFOUND;
234 }
235 
236 /***********************************************************************
237  *
238  * Helper function for DirectDrawCreate and friends
239  * Creates a new DDraw interface with the given REFIID
240  *
241  * Interfaces that can be created:
242  * IDirectDraw, IDirectDraw2, IDirectDraw4, IDirectDraw7
243  * IDirect3D, IDirect3D2, IDirect3D3, IDirect3D7. (Does Windows return
244  * IDirect3D interfaces?)
245  *
246  * Arguments:
247  * guid: ID of the requested driver, NULL for the default driver.
248  * The GUID can be queried with DirectDrawEnumerate(Ex)A/W
249  * DD: Used to return the pointer to the created object
250  * UnkOuter: For aggregation, which is unsupported. Must be NULL
251  * iid: requested version ID.
252  *
253  * Returns:
254  * DD_OK if the Interface was created successfully
255  * CLASS_E_NOAGGREGATION if UnkOuter is not NULL
256  * E_OUTOFMEMORY if some allocation failed
257  *
258  ***********************************************************************/
259 static HRESULT
261  void **DD,
262  IUnknown *UnkOuter,
263  REFIID iid)
264 {
266  struct ddraw *ddraw;
267  HRESULT hr;
268  DWORD flags = 0;
269 
270  TRACE("driver_guid %s, ddraw %p, outer_unknown %p, interface_iid %s.\n",
271  debugstr_guid(guid), DD, UnkOuter, debugstr_guid(iid));
272 
273  *DD = NULL;
274 
275  if (guid == (GUID *) DDCREATE_EMULATIONONLY)
276  {
277  /* Use the reference device id. This doesn't actually change anything,
278  * WineD3D always uses OpenGL for D3D rendering. One could make it request
279  * indirect rendering
280  */
282  }
283  else if(guid == (GUID *) DDCREATE_HARDWAREONLY)
284  {
286  }
287  else
288  {
289  device_type = 0;
290  }
291 
292  /* DDraw doesn't support aggregation, according to msdn */
293  if (UnkOuter != NULL)
294  return CLASS_E_NOAGGREGATION;
295 
296  if (!IsEqualGUID(iid, &IID_IDirectDraw7))
298 
299  /* DirectDraw creation comes here */
300  if (!(ddraw = heap_alloc_zero(sizeof(*ddraw))))
301  {
302  ERR("Out of memory when creating DirectDraw\n");
303  return E_OUTOFMEMORY;
304  }
305 
307  if (FAILED(hr))
308  {
309  WARN("Failed to initialize ddraw object, hr %#x.\n", hr);
310  heap_free(ddraw);
311  return hr;
312  }
313 
314  hr = IDirectDraw7_QueryInterface(&ddraw->IDirectDraw7_iface, iid, DD);
315  IDirectDraw7_Release(&ddraw->IDirectDraw7_iface);
316  if (SUCCEEDED(hr))
318  else
319  WARN("Failed to query interface %s from ddraw object %p.\n", debugstr_guid(iid), ddraw);
320 
321  return hr;
322 }
323 
324 /***********************************************************************
325  * DirectDrawCreate (DDRAW.@)
326  *
327  * Creates legacy DirectDraw Interfaces. Can't create IDirectDraw7
328  * interfaces in theory
329  *
330  * Arguments, return values: See DDRAW_Create
331  *
332  ***********************************************************************/
333 HRESULT WINAPI DECLSPEC_HOTPATCH DirectDrawCreate(GUID *driver_guid, IDirectDraw **ddraw, IUnknown *outer)
334 {
335  HRESULT hr;
336 
337  TRACE("driver_guid %s, ddraw %p, outer %p.\n",
338  debugstr_guid(driver_guid), ddraw, outer);
339 
341  hr = DDRAW_Create(driver_guid, (void **)ddraw, outer, &IID_IDirectDraw);
343 
344  if (SUCCEEDED(hr))
345  {
346  if (FAILED(hr = IDirectDraw_Initialize(*ddraw, driver_guid)))
347  IDirectDraw_Release(*ddraw);
348  }
349 
350  return hr;
351 }
352 
353 /***********************************************************************
354  * DirectDrawCreateEx (DDRAW.@)
355  *
356  * Only creates new IDirectDraw7 interfaces, supposed to fail if legacy
357  * interfaces are requested.
358  *
359  * Arguments, return values: See DDRAW_Create
360  *
361  ***********************************************************************/
363  void **ddraw, REFIID interface_iid, IUnknown *outer)
364 {
365  HRESULT hr;
366 
367  TRACE("driver_guid %s, ddraw %p, interface_iid %s, outer %p.\n",
368  debugstr_guid(driver_guid), ddraw, debugstr_guid(interface_iid), outer);
369 
370  if (!IsEqualGUID(interface_iid, &IID_IDirectDraw7))
371  return DDERR_INVALIDPARAMS;
372 
374  hr = DDRAW_Create(driver_guid, ddraw, outer, interface_iid);
376 
377  if (SUCCEEDED(hr))
378  {
379  IDirectDraw7 *ddraw7 = *(IDirectDraw7 **)ddraw;
380  hr = IDirectDraw7_Initialize(ddraw7, driver_guid);
381  if (FAILED(hr))
382  IDirectDraw7_Release(ddraw7);
383  }
384 
385  return hr;
386 }
387 
388 /***********************************************************************
389  * DirectDrawEnumerateA (DDRAW.@)
390  *
391  * Enumerates legacy ddraw drivers, ascii version. We only have one
392  * driver, which relays to WineD3D. If we were sufficiently cool,
393  * we could offer various interfaces, which use a different default surface
394  * implementation, but I think it's better to offer this choice in
395  * winecfg, because some apps use the default driver, so we would need
396  * a winecfg option anyway, and there shouldn't be 2 ways to set one setting
397  *
398  * Arguments:
399  * Callback: Callback function from the app
400  * Context: Argument to the call back.
401  *
402  * Returns:
403  * DD_OK on success
404  * E_INVALIDARG if the Callback caused a page fault
405  *
406  *
407  ***********************************************************************/
409 {
410  struct callback_info info;
411 
412  TRACE("callback %p, context %p.\n", callback, context);
413 
414  info.callback = callback;
415  info.context = context;
417 }
418 
419 /***********************************************************************
420  * DirectDrawEnumerateExA (DDRAW.@)
421  *
422  * Enumerates DirectDraw7 drivers, ascii version. See
423  * the comments above DirectDrawEnumerateA for more details.
424  *
425  * The Flag member is not supported right now.
426  *
427  ***********************************************************************/
429 {
430  struct wined3d *wined3d;
431 
432  TRACE("callback %p, context %p, flags %#x.\n", callback, context, flags);
433 
437  return DDERR_INVALIDPARAMS;
438 
440  FIXME("flags 0x%08x not handled\n", flags & ~DDENUM_ATTACHEDSECONDARYDEVICES);
441 
442  TRACE("Enumerating ddraw interfaces\n");
444  {
446  {
447  WARN("Failed to create a wined3d object.\n");
448  return E_FAIL;
449  }
450 
451  WARN("Created a wined3d object without 3D support.\n");
452  }
453 
454  __TRY
455  {
456  /* QuickTime expects the description "DirectDraw HAL" */
457  static CHAR driver_desc[] = "DirectDraw HAL",
458  driver_name[] = "display";
459  BOOL cont_enum;
460 
461  TRACE("Default interface: DirectDraw HAL\n");
462  cont_enum = callback(NULL, driver_desc, driver_name, context, 0);
463 
464  /* The Battle.net System Checker expects both a NULL device and a GUID-based device */
465  if (cont_enum && (flags & DDENUM_ATTACHEDSECONDARYDEVICES))
467  }
469  {
471  return DDERR_INVALIDPARAMS;
472  }
473  __ENDTRY;
474 
476  TRACE("End of enumeration\n");
477  return DD_OK;
478 }
479 
480 /***********************************************************************
481  * DirectDrawEnumerateW (DDRAW.@)
482  *
483  * Enumerates legacy drivers, unicode version.
484  * This function is not implemented on Windows.
485  *
486  ***********************************************************************/
488 {
489  TRACE("callback %p, context %p.\n", callback, context);
490 
491  if (!callback)
492  return DDERR_INVALIDPARAMS;
493  else
494  return DDERR_UNSUPPORTED;
495 }
496 
497 /***********************************************************************
498  * DirectDrawEnumerateExW (DDRAW.@)
499  *
500  * Enumerates DirectDraw7 drivers, unicode version.
501  * This function is not implemented on Windows.
502  *
503  ***********************************************************************/
505 {
506  TRACE("callback %p, context %p, flags %#x.\n", callback, context, flags);
507 
508  return DDERR_UNSUPPORTED;
509 }
510 
511 /***********************************************************************
512  * Classfactory implementation.
513  ***********************************************************************/
514 
515 /***********************************************************************
516  * CF_CreateDirectDraw
517  *
518  * DDraw creation function for the class factory
519  *
520  * Params:
521  * UnkOuter: Set to NULL
522  * iid: ID of the wanted interface
523  * obj: Address to pass the interface pointer back
524  *
525  * Returns
526  * DD_OK / DDERR*, see DDRAW_Create
527  *
528  ***********************************************************************/
529 static HRESULT
531  void **obj)
532 {
533  HRESULT hr;
534 
535  TRACE("outer_unknown %p, riid %s, object %p.\n", UnkOuter, debugstr_guid(iid), obj);
536 
538  hr = DDRAW_Create(NULL, obj, UnkOuter, iid);
540 
541  return hr;
542 }
543 
544 /***********************************************************************
545  * CF_CreateDirectDraw
546  *
547  * Clipper creation function for the class factory
548  *
549  * Params:
550  * UnkOuter: Set to NULL
551  * iid: ID of the wanted interface
552  * obj: Address to pass the interface pointer back
553  *
554  * Returns
555  * DD_OK / DDERR*, see DDRAW_Create
556  *
557  ***********************************************************************/
558 static HRESULT
560  void **obj)
561 {
562  HRESULT hr;
563  IDirectDrawClipper *Clip;
564 
565  TRACE("outer_unknown %p, riid %s, object %p.\n", UnkOuter, debugstr_guid(riid), obj);
566 
568  hr = DirectDrawCreateClipper(0, &Clip, UnkOuter);
569  if (hr != DD_OK)
570  {
572  return hr;
573  }
574 
575  hr = IDirectDrawClipper_QueryInterface(Clip, riid, obj);
576  IDirectDrawClipper_Release(Clip);
577 
579 
580  return hr;
581 }
582 
583 static const struct object_creation_info object_creation[] =
584 {
585  { &CLSID_DirectDraw, CF_CreateDirectDraw },
586  { &CLSID_DirectDraw7, CF_CreateDirectDraw },
587  { &CLSID_DirectDrawClipper, CF_CreateDirectDrawClipper }
588 };
589 
591 {
593 
595  HRESULT (*pfnCreateInstance)(IUnknown *outer, REFIID iid, void **out);
596 };
597 
599 {
601 }
602 
603 /*******************************************************************************
604  * IDirectDrawClassFactory::QueryInterface
605  *
606  * QueryInterface for the class factory
607  *
608  * PARAMS
609  * riid Reference to identifier of queried interface
610  * ppv Address to return the interface pointer at
611  *
612  * RETURNS
613  * Success: S_OK
614  * Failure: E_NOINTERFACE
615  *
616  *******************************************************************************/
618 {
619  TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
620 
623  {
624  IClassFactory_AddRef(iface);
625  *out = iface;
626  return S_OK;
627  }
628 
629  WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
630 
631  return E_NOINTERFACE;
632 }
633 
634 /*******************************************************************************
635  * IDirectDrawClassFactory::AddRef
636  *
637  * AddRef for the class factory
638  *
639  * RETURNS
640  * The new refcount
641  *
642  *******************************************************************************/
644 {
647 
648  TRACE("%p increasing refcount to %u.\n", factory, ref);
649 
650  return ref;
651 }
652 
653 /*******************************************************************************
654  * IDirectDrawClassFactory::Release
655  *
656  * Release for the class factory. If the refcount falls to 0, the object
657  * is destroyed
658  *
659  * RETURNS
660  * The new refcount
661  *
662  *******************************************************************************/
664 {
667 
668  TRACE("%p decreasing refcount to %u.\n", factory, ref);
669 
670  if (!ref)
672 
673  return ref;
674 }
675 
676 
677 /*******************************************************************************
678  * IDirectDrawClassFactory::CreateInstance
679  *
680  * What is this? Seems to create DirectDraw objects...
681  *
682  * Params
683  * The usual things???
684  *
685  * RETURNS
686  * ???
687  *
688  *******************************************************************************/
690  IUnknown *outer_unknown, REFIID riid, void **out)
691 {
693 
694  TRACE("iface %p, outer_unknown %p, riid %s, out %p.\n",
695  iface, outer_unknown, debugstr_guid(riid), out);
696 
697  return factory->pfnCreateInstance(outer_unknown, riid, out);
698 }
699 
700 /*******************************************************************************
701  * IDirectDrawClassFactory::LockServer
702  *
703  * What is this?
704  *
705  * Params
706  * ???
707  *
708  * RETURNS
709  * S_OK, because it's a stub
710  *
711  *******************************************************************************/
713 {
714  FIXME("iface %p, dolock %#x stub!\n", iface, dolock);
715 
716  return S_OK;
717 }
718 
719 /*******************************************************************************
720  * The class factory VTable
721  *******************************************************************************/
722 static const IClassFactoryVtbl IClassFactory_Vtbl =
723 {
729 };
730 
732 {
734  unsigned int i;
735 
736  TRACE("rclsid %s, riid %s, out %p.\n",
737  debugstr_guid(rclsid), debugstr_guid(riid), out);
738 
741  return E_NOINTERFACE;
742 
743  for (i=0; i < ARRAY_SIZE(object_creation); i++)
744  {
745  if (IsEqualGUID(object_creation[i].clsid, rclsid))
746  break;
747  }
748 
749  if (i == ARRAY_SIZE(object_creation))
750  {
751  FIXME("%s: no class found.\n", debugstr_guid(rclsid));
753  }
754 
755  if (!(factory = heap_alloc_zero(sizeof(*factory))))
756  return E_OUTOFMEMORY;
757 
759  factory->ref = 1;
760 
761  factory->pfnCreateInstance = object_creation[i].pfnCreateInstance;
762 
763  *out = factory;
764  return S_OK;
765 }
766 
767 
768 /*******************************************************************************
769  * DllCanUnloadNow [DDRAW.@] Determines whether the DLL is in use.
770  *
771  * RETURNS
772  * Success: S_OK
773  * Failure: S_FALSE
774  */
776 {
777  TRACE("\n");
778 
779  return S_FALSE;
780 }
781 
782 
784 {
786 }
787 
789 {
791 }
792 
793 /***********************************************************************
794  * DllMain (DDRAW.0)
795  *
796  * Could be used to register DirectDraw drivers, if we have more than
797  * one. Also used to destroy any objects left at unload if the
798  * app didn't release them properly(Gothic 2, Diablo 2, Moto racer, ...)
799  *
800  ***********************************************************************/
802 {
803  switch (reason)
804  {
805  case DLL_PROCESS_ATTACH:
806  {
807  static HMODULE ddraw_self;
808  HKEY hkey = 0;
809  WNDCLASSA wc;
810 
811  /* Register the window class. This is used to create a hidden window
812  * for D3D rendering, if the application didn't pass one. It can also
813  * be used for creating a device window from SetCooperativeLevel(). */
814  wc.style = CS_HREDRAW | CS_VREDRAW;
816  wc.cbClsExtra = 0;
817  wc.cbWndExtra = 0;
818  wc.hInstance = inst;
819  wc.hIcon = 0;
820  wc.hCursor = 0;
822  wc.lpszMenuName = NULL;
824  if (!RegisterClassA(&wc))
825  {
826  ERR("Failed to register ddraw window class, last error %#x.\n", GetLastError());
827  return FALSE;
828  }
829 
830  /* On Windows one can force the refresh rate that DirectDraw uses by
831  * setting an override value in dxdiag. This is documented in KB315614
832  * (main article), KB230002, and KB217348. By comparing registry dumps
833  * before and after setting the override, we see that the override value
834  * is stored in HKLM\Software\Microsoft\DirectDraw\ForceRefreshRate as a
835  * DWORD that represents the refresh rate to force. We use this
836  * registry entry to modify the behavior of SetDisplayMode so that Wine
837  * users can override the refresh rate in a Windows-compatible way.
838  *
839  * dxdiag will not accept a refresh rate lower than 40 or higher than
840  * 120 so this value should be within that range. It is, of course,
841  * possible for a user to set the registry entry value directly so that
842  * assumption might not hold.
843  *
844  * There is no current mechanism for setting this value through the Wine
845  * GUI. It would be most appropriate to set this value through a dxdiag
846  * clone, but it may be sufficient to use winecfg.
847  *
848  * TODO: Create a mechanism for setting this value through the Wine GUI.
849  */
850  if ( !RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Microsoft\\DirectDraw", &hkey ) )
851  {
852  DWORD type, data, size;
853 
854  size = sizeof(data);
855  if (!RegQueryValueExA(hkey, "ForceRefreshRate", NULL, &type, (BYTE *)&data, &size) && type == REG_DWORD)
856  {
857  TRACE("ForceRefreshRate set; overriding refresh rate to %d Hz\n", data);
859  }
860  RegCloseKey( hkey );
861  }
862 
863  /* Prevent the ddraw module from being unloaded. When switching to
864  * exclusive mode, we replace the window proc of the ddraw window. If
865  * an application would unload ddraw from the WM_DESTROY handler for
866  * that window, it would return to unmapped memory and die. Apparently
867  * this is supposed to work on Windows. */
868 
869  /* ReactOS r61844: Comment out usage of GET_MODULE_HANDLE_EX_FLAG_PIN because it doesn't work */
870  if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS /*| GET_MODULE_HANDLE_EX_FLAG_PIN*/,
871  (const WCHAR *)&ddraw_self, &ddraw_self))
872  ERR("Failed to get own module handle.\n");
873 
874  instance = inst;
876  break;
877  }
878 
879  case DLL_PROCESS_DETACH:
880  if (WARN_ON(ddraw))
881  {
882  struct ddraw *ddraw;
883 
885  {
886  struct ddraw_surface *surface;
887 
888  WARN("DirectDraw object %p has reference counts {%u, %u, %u, %u, %u}.\n",
890 
891  if (ddraw->d3ddevice)
892  WARN("DirectDraw object %p has Direct3D device %p attached.\n", ddraw, ddraw->d3ddevice);
893 
895  {
896  WARN("Surface %p has reference counts {%u, %u, %u, %u, %u, %u}.\n",
897  surface, surface->ref7, surface->ref4, surface->ref3,
898  surface->ref2, surface->ref1, surface->gamma_count);
899  }
900  }
901  }
902 
903  if (reserved) break;
905  }
906 
907  return TRUE;
908 }
HGDIOBJ WINAPI GetStockObject(_In_ int)
#define DDENUM_NONDISPLAYDEVICES
Definition: ddraw.h:193
LONG WINAPI RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3257
#define HRESULT
Definition: msvc.h:9
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4023
static HRESULT WINAPI ddraw_class_factory_LockServer(IClassFactory *iface, BOOL dolock)
Definition: main.c:712
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define REFIID
Definition: guiddef.h:113
#define TRUE
Definition: types.h:120
#define DDCREATE_EMULATIONONLY
Definition: ddraw.h:199
#define E_NOINTERFACE
Definition: winerror.h:2364
HRESULT WINAPI DirectDrawEnumerateA(LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
Definition: main.c:180
HRESULT hr
Definition: shlfolder.c:183
GLint x0
Definition: linetemp.h:95
#define DDERR_UNSUPPORTED
Definition: ddraw.h:127
HRESULT __wine_register_resources(HMODULE module) DECLSPEC_HIDDEN
Definition: register.c:98
WINE_DEFAULT_DEBUG_CHANNEL(wmic)
Definition: http.c:6587
struct list ddraw_list_entry
REFIID riid
Definition: precomp.h:44
static HRESULT WINAPI ddraw_class_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **out)
Definition: main.c:617
#define REFCLSID
Definition: guiddef.h:112
char CHAR
Definition: xmlstorage.h:175
#define WARN(fmt,...)
Definition: debug.h:111
device_type
#define DDCREATE_HARDWAREONLY
Definition: ddraw.h:198
static HDC
Definition: imagelist.c:92
void WINAPI wined3d_mutex_lock(void)
Definition: wined3d_main.c:360
#define CALLBACK
Definition: compat.h:27
__WINE_SERVER_LIST_INLINE void list_add_head(struct list *list, struct list *elem)
Definition: list.h:96
#define DDENUM_DETACHEDSECONDARYDEVICES
Definition: ddraw.h:192
GLdouble GLdouble t
Definition: gl.h:2047
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
void * ddraw_get_object(struct ddraw_handle_table *t, DWORD handle, enum ddraw_handle_type type)
Definition: main.c:182
LONG ref4
Definition: ddraw_private.h:91
int cbClsExtra
Definition: winuser.h:3118
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
const char * wine_dbgstr_guid(const GUID *guid)
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define CS_HREDRAW
Definition: winuser.h:648
LPCSTR lpszMenuName
Definition: winuser.h:3124
HDC dc
Definition: cylfrac.c:34
#define DLL_PROCESS_ATTACH
Definition: compat.h:120
HBRUSH hbrBackground
Definition: winuser.h:3123
const char * description
Definition: directx.c:2502
HRESULT WINAPI DirectDrawCreateClipper(DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
Definition: main.c:55
static struct ddraw_class_factory * impl_from_IClassFactory(IClassFactory *iface)
Definition: main.c:598
static struct list global_ddraw_list
Definition: main.c:36
#define E_FAIL
Definition: ddrawi.h:102
HRESULT WINAPI DirectDrawCreateEx(LPGUID lpGUID, LPVOID *lplpDD, REFIID id, LPUNKNOWN pUnkOuter)
Definition: main.c:139
#define CLASS_E_CLASSNOTAVAILABLE
Definition: winerror.h:2663
Definition: send.c:47
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
struct wined3d *CDECL wined3d_create(DWORD flags)
Definition: wined3d_main.c:96
HRESULT WINAPI DirectDrawCreate(LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
Definition: main.c:86
void * context
Definition: main.c:47
#define WARN_ON(c)
Definition: module.h:255
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
HRESULT WINAPI GetSurfaceFromDC(HDC dc, IDirectDrawSurface4 **surface, HDC *device_dc)
Definition: main.c:202
int cbWndExtra
Definition: winuser.h:3119
#define DD_OK
Definition: ddraw.h:186
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
const GUID * guid
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
HRESULT WINAPI DllRegisterServer(void)
Definition: main.c:212
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
Definition: main.c:440
static const struct object_creation_info object_creation[]
Definition: main.c:583
HRESULT WINAPI DllUnregisterServer(void)
Definition: main.c:220
static ULONG WINAPI ddraw_class_factory_AddRef(IClassFactory *iface)
Definition: main.c:643
IClassFactory IClassFactory_iface
Definition: main.c:592
static HRESULT CF_CreateDirectDraw(IUnknown *UnkOuter, REFIID iid, void **obj)
Definition: main.c:530
GLenum GLint ref
Definition: glext.h:6028
#define FIXME(fmt,...)
Definition: debug.h:110
r reserved
Definition: btrfs.c:2704
HCURSOR hCursor
Definition: winuser.h:3122
unsigned int idx
Definition: utils.c:41
#define S_FALSE
Definition: winerror.h:2357
HRESULT(* pfnCreateInstance)(IUnknown *outer, REFIID iid, void **out)
Definition: main.c:595
#define E_INVALIDARG
Definition: ddrawi.h:101
static void ddraw_enumerate_secondary_devices(struct wined3d *wined3d, LPDDENUMCALLBACKEXA callback, void *context)
Definition: main.c:59
smooth NULL
Definition: ftsmooth.c:416
ddraw_handle_type
#define __TRY
Definition: compat.h:70
#define debugstr_guid
Definition: kernel32.h:35
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct list surface_list_entry
#define DLL_PROCESS_DETACH
Definition: compat.h:119
#define BLACK_BRUSH
Definition: wingdi.h:895
#define DECLSPEC_HOTPATCH
Definition: _mingw.h:240
HRESULT CDECL wined3d_get_adapter_identifier(const struct wined3d *wined3d, UINT adapter_idx, DWORD flags, struct wined3d_adapter_identifier *identifier)
Definition: directx.c:4936
static const IClassFactoryVtbl IClassFactory_Vtbl
Definition: main.c:722
#define CS_VREDRAW
Definition: winuser.h:653
MmuTrapHandler callback[0x30]
Definition: mmuobject.c:44
#define TRACE(s)
Definition: solgame.cpp:4
#define DDERR_NOTFOUND
Definition: ddraw.h:97
GLsizeiptr size
Definition: glext.h:5919
DWORD force_refresh_rate
Definition: main.c:41
static HRESULT WINAPI ddraw_class_factory_CreateInstance(IClassFactory *iface, IUnknown *outer_unknown, REFIID riid, void **out)
Definition: main.c:689
struct d3d_device * d3ddevice
#define LIST_INIT(head)
Definition: queue.h:197
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define DDRAW_INVALID_HANDLE
ULONG CDECL wined3d_decref(struct wined3d *wined3d)
Definition: directx.c:466
LONG HRESULT
Definition: typedefs.h:77
const GUID IID_IUnknown
#define WINAPI
Definition: msvc.h:8
#define DDRAW_WINDOW_CLASS_NAME
static FILE * out
Definition: regtests2xml.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
HMONITOR monitor
Definition: wined3d.h:2106
void ddraw_handle_table_destroy(struct ddraw_handle_table *t)
Definition: main.c:107
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161
HRESULT CDECL wined3d_get_output_desc(const struct wined3d *wined3d, unsigned int adapter_idx, struct wined3d_output_desc *desc)
Definition: directx.c:4496
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1904
#define __ENDTRY
Definition: compat.h:72
static HRESULT CF_CreateDirectDrawClipper(IUnknown *UnkOuter, REFIID riid, void **obj)
Definition: main.c:559
struct list surface_list
REFCLSID clsid
Definition: msctf.c:84
#define InterlockedDecrement
Definition: armddk.h:52
static HRESULT DDRAW_Create(const GUID *guid, void **DD, IUnknown *UnkOuter, REFIID iid)
Definition: main.c:260
HRESULT __wine_unregister_resources(HMODULE module) DECLSPEC_HIDDEN
Definition: register.c:110
void * ddraw_free_handle(struct ddraw_handle_table *t, DWORD handle, enum ddraw_handle_type type)
Definition: main.c:156
HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type device_type)
Definition: ddraw.c:5021
uint32_t entry
Definition: isohybrid.c:63
IDirectDraw4 IDirectDraw4_iface
Definition: ddraw_private.h:81
unsigned char BYTE
Definition: mem.h:68
#define DDENUM_ATTACHEDSECONDARYDEVICES
Definition: ddraw.h:191
Definition: _list.h:228
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
#define DDRAW_WINED3D_FLAGS
Definition: ddraw_private.h:65
LPCSTR lpszClassName
Definition: winuser.h:3125
BOOL ddraw_handle_table_init(struct ddraw_handle_table *t, UINT initial_size)
Definition: main.c:93
UINT style
Definition: winuser.h:3116
#define ERR(fmt,...)
Definition: debug.h:109
#define WINED3D_LEGACY_FFP_LIGHTING
Definition: wined3d.h:1325
BOOL WINAPI GetModuleHandleExW(IN DWORD dwFlags, IN LPCWSTR lpwModuleName OPTIONAL, OUT HMODULE *phModule)
Definition: loader.c:873
#define S_OK
Definition: intsafe.h:59
#define InterlockedIncrement
Definition: armddk.h:53
int type
Definition: main.c:85
HINSTANCE hInstance
Definition: winuser.h:3120
HRESULT WINAPI DirectDrawEnumerateW(LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
Definition: main.c:267
#define DD(x)
#define ARRAY_SIZE(a)
Definition: main.h:24
wined3d_device_type
Definition: wined3d.h:85
LONG ref2
Definition: ddraw_private.h:91
DWORD IDirectDraw7
Definition: vmrender.idl:21
HRESULT WINAPI DirectDrawEnumerateExW(LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
Definition: main.c:277
HRESULT WINAPI DllCanUnloadNow(void)
Definition: main.c:204
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
static BOOL CALLBACK enum_callback(GUID *guid, char *description, char *driver_name, void *context, HMONITOR monitor)
Definition: main.c:51
LONG ref3
Definition: ddraw_private.h:91
WNDPROC lpfnWndProc
Definition: winuser.h:3117
DWORD ddraw_allocate_handle(struct ddraw_handle_table *t, void *object, enum ddraw_handle_type type)
Definition: main.c:113
LONG ref7
Definition: ddraw_private.h:91
HRESULT WINAPI DirectDrawEnumerateExA(LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
Definition: main.c:208
LPDDENUMCALLBACKA callback
Definition: main.c:46
unsigned int ULONG
Definition: retypes.h:1
static ClassFactoryImpl factory
Definition: ole_server.c:234
IDirectDraw7 IDirectDraw7_iface
Definition: ddraw_private.h:80
BOOL WINAPI UnregisterClassA(_In_ LPCSTR, HINSTANCE)
#define WINED3D_NO3D
Definition: wined3d.h:1318
void WINAPI wined3d_mutex_unlock(void)
Definition: wined3d_main.c:365
const GUID IID_IClassFactory
#define memset(x, y, z)
Definition: compat.h:39
#define REG_DWORD
Definition: sdbapi.c:596
IClassFactory IClassFactory_iface
Definition: main.c:442
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
#define DDERR_INVALIDPARAMS
Definition: ddraw.h:79
static ULONG WINAPI ddraw_class_factory_Release(IClassFactory *iface)
Definition: main.c:663
void * object
Definition: jmemsys.h:48
#define __EXCEPT_PAGE_FAULT
Definition: compat.h:71
LONG ref1
Definition: ddraw_private.h:91
#define SUCCEEDED(hr)
Definition: intsafe.h:57
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
Definition: main.c:166
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
Definition: main.c:26
HICON hIcon
Definition: winuser.h:3121
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
static HINSTANCE instance
Definition: main.c:38