Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

169 lines
3.8 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. UltimateSoccerManager.cpp
  5. Abstract:
  6. A hack for Ultimate Soccer Manager (Sierra Sports). The game caches a
  7. pointer to a ddraw system memory surface. It later uses that pointer even
  8. after the surface has been freed.
  9. This worked on Win9x by blind luck: when they re-create a new surface, it
  10. happened to end up in the same system memory as before.
  11. Notes:
  12. This is an app specific shim.
  13. History:
  14. 01/07/2000 linstev Created
  15. --*/
  16. #include "precomp.h"
  17. IMPLEMENT_SHIM_BEGIN(UltimateSoccerManager)
  18. #include "ShimHookMacro.h"
  19. APIHOOK_ENUM_BEGIN
  20. APIHOOK_ENUM_ENTRY_DIRECTX_COMSERVER()
  21. APIHOOK_ENUM_END
  22. IMPLEMENT_DIRECTX_COMSERVER_HOOKS()
  23. // Keep a list of cached surfaces
  24. struct SLIST
  25. {
  26. struct SLIST *next;
  27. DDSURFACEDESC ddsd;
  28. LPDIRECTDRAWSURFACE lpDDSurface;
  29. };
  30. SLIST *g_SList = NULL;
  31. /*++
  32. Hook create surface so we can return the cached surface if possible.
  33. --*/
  34. HRESULT
  35. COMHOOK(IDirectDraw, CreateSurface)(
  36. PVOID pThis,
  37. LPDDSURFACEDESC lpDDSurfaceDesc,
  38. LPDIRECTDRAWSURFACE* lplpDDSurface,
  39. IUnknown* pUnkOuter
  40. )
  41. {
  42. HRESULT hReturn;
  43. // Retrieve the old function
  44. _pfn_IDirectDraw_CreateSurface pfnOld =
  45. ORIGINAL_COM(IDirectDraw, CreateSurface, pThis);
  46. SLIST *surf = g_SList, *last = NULL;
  47. while (surf)
  48. {
  49. // Check for the same kind of surface.
  50. if ((lpDDSurfaceDesc->ddsCaps.dwCaps == surf->ddsd.ddsCaps.dwCaps) &&
  51. (lpDDSurfaceDesc->dwWidth == surf->ddsd.dwWidth) &&
  52. (lpDDSurfaceDesc->dwHeight == surf->ddsd.dwHeight))
  53. {
  54. *lplpDDSurface = surf->lpDDSurface;
  55. if (last)
  56. {
  57. last->next = surf->next;
  58. }
  59. else
  60. {
  61. g_SList = surf->next;
  62. }
  63. free(surf);
  64. DPFN( eDbgLevelInfo, "Returning cached surface %08lx\n", *lplpDDSurface);
  65. return DD_OK;
  66. }
  67. last = surf;
  68. surf = surf->next;
  69. }
  70. if (SUCCEEDED(hReturn = (*pfnOld)(
  71. pThis,
  72. lpDDSurfaceDesc,
  73. lplpDDSurface,
  74. pUnkOuter)))
  75. {
  76. HookObject(
  77. NULL,
  78. IID_IDirectDrawSurface,
  79. (PVOID*)lplpDDSurface,
  80. NULL,
  81. FALSE);
  82. }
  83. return hReturn;
  84. }
  85. /*++
  86. If it's a system memory surface, go ahead and cache it if we're about to
  87. release it anyway.
  88. --*/
  89. ULONG
  90. COMHOOK(IDirectDrawSurface, Release)(
  91. LPDIRECTDRAWSURFACE lpDDSurface
  92. )
  93. {
  94. lpDDSurface->AddRef();
  95. // Retrieve the old function
  96. _pfn_IDirectDrawSurface_Release pfnOld = ORIGINAL_COM(IDirectDrawSurface, Release, (LPVOID) lpDDSurface);
  97. ULONG uRet = (*pfnOld)(lpDDSurface);
  98. if (uRet == 1)
  99. {
  100. DDSURFACEDESC ddsd = {sizeof(ddsd)};
  101. if (SUCCEEDED(lpDDSurface->GetSurfaceDesc(&ddsd)) &&
  102. (ddsd.ddsCaps.dwCaps ==
  103. (DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY)))
  104. {
  105. SLIST *surf = (SLIST *) malloc(sizeof(SLIST));
  106. surf->next = g_SList;
  107. MoveMemory(&surf->ddsd, &ddsd, sizeof(ddsd));
  108. surf->lpDDSurface = lpDDSurface;
  109. g_SList = surf;
  110. DPFN( eDbgLevelInfo, "Surface %08lx is being cached\n", lpDDSurface);
  111. return 0;
  112. }
  113. }
  114. return (*pfnOld)(lpDDSurface);
  115. }
  116. /*++
  117. Register hooked functions
  118. --*/
  119. HOOK_BEGIN
  120. APIHOOK_ENTRY_DIRECTX_COMSERVER()
  121. COMHOOK_ENTRY(DirectDraw, IDirectDraw, CreateSurface, 6)
  122. COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface, Release, 2)
  123. HOOK_END
  124. IMPLEMENT_SHIM_END