Source code of Windows XP (NT5)
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.

351 lines
7.1 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. ForceDirectDrawWait.cpp
  5. Abstract:
  6. Some applications don't specify the DD_WAIT flag to
  7. IDirectDrawSurface::Lock, which means that if it fails because the device
  8. is busy, the app can fail. This could also happen on Win9x of course, but
  9. was more difficult to repro.
  10. Note that we don't need to do this on the IDirectDraw7 interface since the
  11. default is DDLOCK_WAIT, unless DDLOCK_DONOTWAIT is specified.
  12. Notes:
  13. This is a general purpose shim.
  14. History:
  15. 03/04/2000 linstev Created
  16. --*/
  17. #include "precomp.h"
  18. IMPLEMENT_SHIM_BEGIN(ForceDirectDrawWait)
  19. #include "ShimHookMacro.h"
  20. APIHOOK_ENUM_BEGIN
  21. APIHOOK_ENUM_ENTRY_DIRECTX_COMSERVER()
  22. APIHOOK_ENUM_END
  23. IMPLEMENT_DIRECTX_COMSERVER_HOOKS()
  24. /*++
  25. Hook create surface so we can be sure we're being called.
  26. --*/
  27. HRESULT
  28. COMHOOK(IDirectDraw, CreateSurface)(
  29. PVOID pThis,
  30. LPDDSURFACEDESC lpDDSurfaceDesc,
  31. LPDIRECTDRAWSURFACE* lplpDDSurface,
  32. IUnknown* pUnkOuter
  33. )
  34. {
  35. HRESULT hReturn;
  36. _pfn_IDirectDraw_CreateSurface pfnOld =
  37. ORIGINAL_COM(IDirectDraw, CreateSurface, pThis);
  38. if (SUCCEEDED(hReturn = (*pfnOld)(
  39. pThis,
  40. lpDDSurfaceDesc,
  41. lplpDDSurface,
  42. pUnkOuter)))
  43. {
  44. HookObject(
  45. NULL,
  46. IID_IDirectDrawSurface,
  47. (PVOID*)lplpDDSurface,
  48. NULL,
  49. FALSE);
  50. }
  51. return hReturn;
  52. }
  53. /*++
  54. Hook create surface so we can be sure we're being called.
  55. --*/
  56. HRESULT
  57. COMHOOK(IDirectDraw2, CreateSurface)(
  58. PVOID pThis,
  59. LPDDSURFACEDESC lpDDSurfaceDesc,
  60. LPDIRECTDRAWSURFACE* lplpDDSurface,
  61. IUnknown* pUnkOuter
  62. )
  63. {
  64. HRESULT hReturn;
  65. _pfn_IDirectDraw2_CreateSurface pfnOld =
  66. ORIGINAL_COM(IDirectDraw2, CreateSurface, pThis);
  67. if (SUCCEEDED(hReturn = (*pfnOld)(
  68. pThis,
  69. lpDDSurfaceDesc,
  70. lplpDDSurface,
  71. pUnkOuter)))
  72. {
  73. HookObject(
  74. NULL,
  75. IID_IDirectDrawSurface2,
  76. (PVOID*)lplpDDSurface,
  77. NULL,
  78. FALSE);
  79. }
  80. return hReturn;
  81. }
  82. /*++
  83. Hook create surface so we can be sure we're being called.
  84. --*/
  85. HRESULT
  86. COMHOOK(IDirectDraw4, CreateSurface)(
  87. PVOID pThis,
  88. LPDDSURFACEDESC2 lpDDSurfaceDesc,
  89. LPDIRECTDRAWSURFACE* lplpDDSurface,
  90. IUnknown* pUnkOuter
  91. )
  92. {
  93. HRESULT hReturn;
  94. _pfn_IDirectDraw4_CreateSurface pfnOld =
  95. ORIGINAL_COM(IDirectDraw4, CreateSurface, pThis);
  96. if (SUCCEEDED(hReturn = (*pfnOld)(
  97. pThis,
  98. lpDDSurfaceDesc,
  99. lplpDDSurface,
  100. pUnkOuter)))
  101. {
  102. HookObject(
  103. NULL,
  104. IID_IDirectDrawSurface4,
  105. (PVOID*)lplpDDSurface,
  106. NULL,
  107. FALSE);
  108. }
  109. return hReturn;
  110. }
  111. /*++
  112. Make sure we add DDBLT_WAIT.
  113. --*/
  114. HRESULT
  115. COMHOOK(IDirectDrawSurface, Blt)(
  116. LPDIRECTDRAWSURFACE lpDDDestSurface,
  117. LPRECT lpDestRect,
  118. LPDIRECTDRAWSURFACE lpDDSrcSurface,
  119. LPRECT lpSrcRect,
  120. DWORD dwFlags,
  121. LPDDBLTFX lpDDBltFX
  122. )
  123. {
  124. dwFlags &= ~DDBLT_DONOTWAIT;
  125. dwFlags |= DDBLT_WAIT;
  126. // Original Blt
  127. _pfn_IDirectDrawSurface_Blt pfnOld = ORIGINAL_COM(
  128. IDirectDrawSurface,
  129. Blt,
  130. lpDDDestSurface);
  131. return (*pfnOld)(
  132. lpDDDestSurface,
  133. lpDestRect,
  134. lpDDSrcSurface,
  135. lpSrcRect,
  136. dwFlags,
  137. lpDDBltFX);
  138. }
  139. HRESULT
  140. COMHOOK(IDirectDrawSurface2, Blt)(
  141. LPDIRECTDRAWSURFACE lpDDDestSurface,
  142. LPRECT lpDestRect,
  143. LPDIRECTDRAWSURFACE lpDDSrcSurface,
  144. LPRECT lpSrcRect,
  145. DWORD dwFlags,
  146. LPDDBLTFX lpDDBltFX
  147. )
  148. {
  149. dwFlags &= ~DDBLT_DONOTWAIT;
  150. dwFlags |= DDBLT_WAIT;
  151. // Original Blt
  152. _pfn_IDirectDrawSurface_Blt pfnOld = ORIGINAL_COM(
  153. IDirectDrawSurface2,
  154. Blt,
  155. lpDDDestSurface);
  156. return (*pfnOld)(
  157. lpDDDestSurface,
  158. lpDestRect,
  159. lpDDSrcSurface,
  160. lpSrcRect,
  161. dwFlags,
  162. lpDDBltFX);
  163. }
  164. HRESULT
  165. COMHOOK(IDirectDrawSurface4, Blt)(
  166. LPDIRECTDRAWSURFACE lpDDDestSurface,
  167. LPRECT lpDestRect,
  168. LPDIRECTDRAWSURFACE lpDDSrcSurface,
  169. LPRECT lpSrcRect,
  170. DWORD dwFlags,
  171. LPDDBLTFX lpDDBltFX
  172. )
  173. {
  174. dwFlags &= ~DDBLT_DONOTWAIT;
  175. dwFlags |= DDBLT_WAIT;
  176. // Original Blt
  177. _pfn_IDirectDrawSurface_Blt pfnOld = ORIGINAL_COM(
  178. IDirectDrawSurface4,
  179. Blt,
  180. lpDDDestSurface);
  181. return (*pfnOld)(
  182. lpDDDestSurface,
  183. lpDestRect,
  184. lpDDSrcSurface,
  185. lpSrcRect,
  186. dwFlags,
  187. lpDDBltFX);
  188. }
  189. /*++
  190. Make sure we add DDLOCK_WAIT.
  191. --*/
  192. HRESULT
  193. COMHOOK(IDirectDrawSurface, Lock)(
  194. LPDIRECTDRAWSURFACE lpDDSurface,
  195. LPRECT lpDestRect,
  196. LPDDSURFACEDESC lpDDSurfaceDesc,
  197. DWORD dwFlags,
  198. HANDLE hEvent
  199. )
  200. {
  201. dwFlags &= ~DDLOCK_DONOTWAIT;
  202. dwFlags |= DDLOCK_WAIT;
  203. // Retrieve the old function
  204. _pfn_IDirectDrawSurface_Lock pfnOld = ORIGINAL_COM(
  205. IDirectDrawSurface,
  206. Lock,
  207. lpDDSurface);
  208. // Call the old API
  209. return (*pfnOld)(
  210. lpDDSurface,
  211. lpDestRect,
  212. lpDDSurfaceDesc,
  213. dwFlags,
  214. hEvent);
  215. }
  216. HRESULT
  217. COMHOOK(IDirectDrawSurface2, Lock)(
  218. LPDIRECTDRAWSURFACE lpDDSurface,
  219. LPRECT lpDestRect,
  220. LPDDSURFACEDESC lpDDSurfaceDesc,
  221. DWORD dwFlags,
  222. HANDLE hEvent
  223. )
  224. {
  225. dwFlags &= ~DDLOCK_DONOTWAIT;
  226. dwFlags |= DDLOCK_WAIT;
  227. // Retrieve the old function
  228. _pfn_IDirectDrawSurface_Lock pfnOld = ORIGINAL_COM(
  229. IDirectDrawSurface2,
  230. Lock,
  231. lpDDSurface);
  232. // Call the old API
  233. return (*pfnOld)(
  234. lpDDSurface,
  235. lpDestRect,
  236. lpDDSurfaceDesc,
  237. dwFlags,
  238. hEvent);
  239. }
  240. HRESULT
  241. COMHOOK(IDirectDrawSurface4, Lock)(
  242. LPDIRECTDRAWSURFACE lpDDSurface,
  243. LPRECT lpDestRect,
  244. LPDDSURFACEDESC lpDDSurfaceDesc,
  245. DWORD dwFlags,
  246. HANDLE hEvent
  247. )
  248. {
  249. dwFlags &= ~DDLOCK_DONOTWAIT;
  250. dwFlags |= DDLOCK_WAIT;
  251. // Retrieve the old function
  252. _pfn_IDirectDrawSurface_Lock pfnOld = ORIGINAL_COM(
  253. IDirectDrawSurface4,
  254. Lock,
  255. lpDDSurface);
  256. // Call the old API
  257. return (*pfnOld)(
  258. lpDDSurface,
  259. lpDestRect,
  260. lpDDSurfaceDesc,
  261. dwFlags,
  262. hEvent);
  263. }
  264. /*++
  265. Register hooked functions
  266. --*/
  267. HOOK_BEGIN
  268. APIHOOK_ENTRY_DIRECTX_COMSERVER()
  269. COMHOOK_ENTRY(DirectDraw, IDirectDraw, CreateSurface, 6)
  270. COMHOOK_ENTRY(DirectDraw, IDirectDraw2, CreateSurface, 6)
  271. COMHOOK_ENTRY(DirectDraw, IDirectDraw4, CreateSurface, 6)
  272. COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface, Blt, 5)
  273. COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface2, Blt, 5)
  274. COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface4, Blt, 5)
  275. COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface, Lock, 25)
  276. COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface2, Lock, 25)
  277. COMHOOK_ENTRY(DirectDraw, IDirectDrawSurface4, Lock, 25)
  278. HOOK_END
  279. IMPLEMENT_SHIM_END