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.

439 lines
10 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. CorrectCreateSurface.cpp
  5. Abstract:
  6. Clean up bad ddraw CreateSurface caps.
  7. Command Line FIX;CHK:Flags;DEL:Flags;ADD=Flags
  8. e.g., - FIX;CHK:DDSCAPS_TEXTURE;DEL:DDSCAPS_3DDEVICE
  9. FIX - Sets the flags which indicate whether to
  10. fix the flags and call the interface or to
  11. make a call and retry after fixing caps if the call fails.
  12. The default is to call the interface with
  13. passed in parameters and if the call fails
  14. then the flags are fixed and a retry is made.
  15. CHK - Check for flags (condition)
  16. ADD - Add flags
  17. DEL - Delete flags
  18. Notes:
  19. This is a general purpose shim.
  20. History:
  21. 02/16/2001 a-leelat Created
  22. 02/13/2002 astritz Security Review
  23. --*/
  24. #include "precomp.h"
  25. IMPLEMENT_SHIM_BEGIN(CorrectCreateSurface)
  26. #include "ShimHookMacro.h"
  27. APIHOOK_ENUM_BEGIN
  28. APIHOOK_ENUM_ENTRY_DIRECTX_COMSERVER()
  29. APIHOOK_ENUM_END
  30. IMPLEMENT_DIRECTX_COMSERVER_HOOKS()
  31. DWORD g_dwFlagsChk = 0;
  32. DWORD g_dwFlagsAdd = 0;
  33. DWORD g_dwFlagsDel = 0;
  34. BOOL g_bTryAndFix = TRUE;
  35. struct DDFLAGS
  36. {
  37. WCHAR * lpszFlagName;
  38. DWORD dwFlag;
  39. };
  40. //Hold the falg entries
  41. //add any undefined flags to this array
  42. static DDFLAGS g_DDFlags[] =
  43. {
  44. {L"DDSCAPS_3DDEVICE", DDSCAPS_3DDEVICE},
  45. {L"DDSCAPS_ALLOCONLOAD", DDSCAPS_ALLOCONLOAD},
  46. {L"DDSCAPS_ALPHA", DDSCAPS_ALPHA},
  47. {L"DDSCAPS_BACKBUFFER", DDSCAPS_BACKBUFFER},
  48. {L"DDSCAPS_COMPLEX", DDSCAPS_COMPLEX},
  49. {L"DDSCAPS_FLIP", DDSCAPS_FLIP},
  50. {L"DDSCAPS_FRONTBUFFER", DDSCAPS_FRONTBUFFER},
  51. {L"DDSCAPS_HWCODEC", DDSCAPS_HWCODEC},
  52. {L"DDSCAPS_LIVEVIDEO", DDSCAPS_LIVEVIDEO},
  53. {L"DDSCAPS_LOCALVIDMEM", DDSCAPS_LOCALVIDMEM},
  54. {L"DDSCAPS_MIPMAP", DDSCAPS_MIPMAP},
  55. {L"DDSCAPS_MODEX", DDSCAPS_MODEX},
  56. {L"DDSCAPS_NONLOCALVIDMEM", DDSCAPS_NONLOCALVIDMEM},
  57. {L"DDSCAPS_OFFSCREENPLAIN", DDSCAPS_OFFSCREENPLAIN},
  58. {L"DDSCAPS_OPTIMIZED", DDSCAPS_OPTIMIZED},
  59. {L"DDSCAPS_OVERLAY", DDSCAPS_OVERLAY},
  60. {L"DDSCAPS_OWNDC", DDSCAPS_OWNDC},
  61. {L"DDSCAPS_PALETTE", DDSCAPS_PALETTE},
  62. {L"DDSCAPS_PRIMARYSURFACE", DDSCAPS_PRIMARYSURFACE},
  63. {L"DDSCAPS_STANDARDVGAMODE", DDSCAPS_STANDARDVGAMODE},
  64. {L"DDSCAPS_SYSTEMMEMORY", DDSCAPS_SYSTEMMEMORY},
  65. {L"DDSCAPS_TEXTURE", DDSCAPS_TEXTURE},
  66. {L"DDSCAPS_VIDEOMEMORY", DDSCAPS_VIDEOMEMORY},
  67. {L"DDSCAPS_VIDEOPORT", DDSCAPS_VIDEOPORT},
  68. {L"DDSCAPS_VISIBLE", DDSCAPS_VISIBLE},
  69. {L"DDSCAPS_WRITEONLY", DDSCAPS_WRITEONLY},
  70. {L"DDSCAPS_ZBUFFER", DDSCAPS_ZBUFFER},
  71. };
  72. #define DDFLAGSSIZE sizeof(g_DDFlags) / sizeof(g_DDFlags[0])
  73. DWORD GetDWord(const CString & lpFlag)
  74. {
  75. for ( int i = 0; i < DDFLAGSSIZE; i++ )
  76. {
  77. if (lpFlag.CompareNoCase(g_DDFlags[i].lpszFlagName) == 0)
  78. {
  79. return g_DDFlags[i].dwFlag;
  80. }
  81. }
  82. return 0;
  83. }
  84. const WCHAR * GetName(DWORD dwDDSCAPS)
  85. {
  86. for ( int i = 0; i < DDFLAGSSIZE; i++ )
  87. {
  88. if (g_DDFlags[i].dwFlag == dwDDSCAPS)
  89. {
  90. return g_DDFlags[i].lpszFlagName;
  91. }
  92. }
  93. return NULL;
  94. }
  95. VOID FixCaps(LPDDSURFACEDESC lpDDSurfaceDesc)
  96. {
  97. if ( lpDDSurfaceDesc->dwFlags & DDSD_CAPS )
  98. {
  99. //To Check
  100. if( !lpDDSurfaceDesc->ddsCaps.dwCaps || lpDDSurfaceDesc->ddsCaps.dwCaps & g_dwFlagsChk )
  101. {
  102. //To remove
  103. lpDDSurfaceDesc->ddsCaps.dwCaps &= ~g_dwFlagsDel;
  104. //To add
  105. lpDDSurfaceDesc->ddsCaps.dwCaps |= g_dwFlagsAdd;
  106. }
  107. }
  108. }
  109. VOID FixCaps2(LPDDSURFACEDESC2 lpDDSurfaceDesc)
  110. {
  111. if ( lpDDSurfaceDesc->dwFlags & DDSD_CAPS )
  112. {
  113. //To Check
  114. if ( !lpDDSurfaceDesc->ddsCaps.dwCaps || lpDDSurfaceDesc->ddsCaps.dwCaps & g_dwFlagsChk )
  115. {
  116. //To remove
  117. lpDDSurfaceDesc->ddsCaps.dwCaps &= ~g_dwFlagsDel;
  118. //To add
  119. lpDDSurfaceDesc->ddsCaps.dwCaps |= g_dwFlagsAdd;
  120. }
  121. }
  122. }
  123. HRESULT
  124. COMHOOK(IDirectDraw, CreateSurface)(
  125. PVOID pThis,
  126. LPDDSURFACEDESC lpDDSurfaceDesc,
  127. LPDIRECTDRAWSURFACE* lplpDDSurface,
  128. IUnknown* pUnkOuter
  129. )
  130. {
  131. _pfn_IDirectDraw_CreateSurface pfnOld =
  132. ORIGINAL_COM(IDirectDraw, CreateSurface, pThis);
  133. //Fix it anyway
  134. if ( !g_bTryAndFix )
  135. FixCaps(lpDDSurfaceDesc);
  136. HRESULT hRet = (*pfnOld)(
  137. pThis,
  138. lpDDSurfaceDesc,
  139. lplpDDSurface,
  140. pUnkOuter);
  141. if ( (hRet == DDERR_INVALIDCAPS) || (hRet == DDERR_INVALIDPIXELFORMAT)||
  142. (hRet == DDERR_UNSUPPORTED) || (hRet == DDERR_OUTOFVIDEOMEMORY ) ||
  143. (hRet == DDERR_INVALIDPARAMS) )
  144. {
  145. FixCaps(lpDDSurfaceDesc);
  146. hRet = (*pfnOld)(
  147. pThis,
  148. lpDDSurfaceDesc,
  149. lplpDDSurface,
  150. pUnkOuter);
  151. }
  152. return hRet;
  153. }
  154. /*++
  155. Hook create surface and fix parameters
  156. --*/
  157. HRESULT
  158. COMHOOK(IDirectDraw2, CreateSurface)(
  159. PVOID pThis,
  160. LPDDSURFACEDESC lpDDSurfaceDesc,
  161. LPDIRECTDRAWSURFACE* lplpDDSurface,
  162. IUnknown* pUnkOuter
  163. )
  164. {
  165. _pfn_IDirectDraw2_CreateSurface pfnOld =
  166. ORIGINAL_COM(IDirectDraw2, CreateSurface, pThis);
  167. //Fix it anyway
  168. if ( !g_bTryAndFix )
  169. FixCaps(lpDDSurfaceDesc);
  170. HRESULT hRet = (*pfnOld)(
  171. pThis,
  172. lpDDSurfaceDesc,
  173. lplpDDSurface,
  174. pUnkOuter);
  175. if ( (hRet == DDERR_INVALIDCAPS) || (hRet == DDERR_INVALIDPIXELFORMAT) ||
  176. (hRet == DDERR_UNSUPPORTED) || (hRet == DDERR_OUTOFVIDEOMEMORY ) ||
  177. (hRet == DDERR_INVALIDPARAMS) )
  178. {
  179. FixCaps(lpDDSurfaceDesc);
  180. hRet = (*pfnOld)(
  181. pThis,
  182. lpDDSurfaceDesc,
  183. lplpDDSurface,
  184. pUnkOuter);
  185. }
  186. return hRet;
  187. }
  188. /*++
  189. Hook create surface and fix parameters
  190. --*/
  191. HRESULT
  192. COMHOOK(IDirectDraw4, CreateSurface)(
  193. PVOID pThis,
  194. LPDDSURFACEDESC2 lpDDSurfaceDesc,
  195. LPDIRECTDRAWSURFACE* lplpDDSurface,
  196. IUnknown* pUnkOuter
  197. )
  198. {
  199. _pfn_IDirectDraw4_CreateSurface pfnOld =
  200. ORIGINAL_COM(IDirectDraw4, CreateSurface, pThis);
  201. //Fix it anyway
  202. if ( !g_bTryAndFix )
  203. FixCaps2(lpDDSurfaceDesc);
  204. HRESULT hRet = (*pfnOld)(
  205. pThis,
  206. lpDDSurfaceDesc,
  207. lplpDDSurface,
  208. pUnkOuter);
  209. if ( (hRet == DDERR_INVALIDCAPS) || (hRet == DDERR_INVALIDPIXELFORMAT) ||
  210. (hRet == DDERR_UNSUPPORTED) || (hRet == DDERR_OUTOFVIDEOMEMORY ) ||
  211. (hRet == DDERR_INVALIDPARAMS) )
  212. {
  213. FixCaps2(lpDDSurfaceDesc);
  214. hRet = (*pfnOld)(
  215. pThis,
  216. lpDDSurfaceDesc,
  217. lplpDDSurface,
  218. pUnkOuter);
  219. }
  220. return hRet;
  221. }
  222. /*++
  223. Hook create surface and fix parameters
  224. --*/
  225. HRESULT
  226. COMHOOK(IDirectDraw7, CreateSurface)(
  227. PVOID pThis,
  228. LPDDSURFACEDESC2 lpDDSurfaceDesc,
  229. LPDIRECTDRAWSURFACE* lplpDDSurface,
  230. IUnknown* pUnkOuter
  231. )
  232. {
  233. _pfn_IDirectDraw7_CreateSurface pfnOld =
  234. ORIGINAL_COM(IDirectDraw7, CreateSurface, pThis);
  235. if ( !g_bTryAndFix )
  236. FixCaps2(lpDDSurfaceDesc);
  237. HRESULT hRet = (*pfnOld)(
  238. pThis,
  239. lpDDSurfaceDesc,
  240. lplpDDSurface,
  241. pUnkOuter);
  242. if ( (hRet == DDERR_INVALIDCAPS) || (hRet == DDERR_INVALIDPIXELFORMAT) ||
  243. (hRet == DDERR_UNSUPPORTED) || (hRet == DDERR_OUTOFVIDEOMEMORY) ||
  244. (hRet == DDERR_INVALIDPARAMS ) )
  245. {
  246. FixCaps2(lpDDSurfaceDesc);
  247. hRet = (*pfnOld)(
  248. pThis,
  249. lpDDSurfaceDesc,
  250. lplpDDSurface,
  251. pUnkOuter);
  252. }
  253. return hRet;
  254. }
  255. BOOL
  256. ParseCommandLine(const char * lpszCommandLine)
  257. {
  258. CSTRING_TRY
  259. {
  260. DPFN( eDbgLevelInfo, "[ParseCommandLine] CommandLine(%s)\n", lpszCommandLine);
  261. CStringToken csCommandLine(lpszCommandLine, ";|:=");
  262. CString csOperator;
  263. while (csCommandLine.GetToken(csOperator))
  264. {
  265. if (csOperator.CompareNoCase(L"Fix") == 0)
  266. {
  267. //Go ahead and fix the caps
  268. //before we make the call.
  269. g_bTryAndFix = FALSE;
  270. DPFN( eDbgLevelInfo, "[ParseCommandLine] Do not fix\n", lpszCommandLine);
  271. }
  272. else
  273. {
  274. // The next token is the caps to add
  275. CString csDDSCAPS;
  276. csCommandLine.GetToken(csDDSCAPS);
  277. DWORD dwDDSCAPS = GetDWord(csDDSCAPS); // returns 0 for unknown DDSCAPS
  278. if (dwDDSCAPS)
  279. {
  280. if (csOperator.CompareNoCase(L"Add") == 0)
  281. {
  282. DPFN( eDbgLevelInfo, "[ParseCommandLine] Add(%S)\n", GetName(dwDDSCAPS));
  283. g_dwFlagsAdd |= dwDDSCAPS;
  284. }
  285. else if (csOperator.CompareNoCase(L"Del") == 0)
  286. {
  287. DPFN( eDbgLevelInfo, "[ParseCommandLine] Del(%S)\n", GetName(dwDDSCAPS));
  288. g_dwFlagsDel |= dwDDSCAPS;
  289. }
  290. else if (csOperator.CompareNoCase(L"Chk") == 0)
  291. {
  292. DPFN( eDbgLevelInfo, "[ParseCommandLine] Chk(%S)\n", GetName(dwDDSCAPS));
  293. g_dwFlagsChk |= dwDDSCAPS;
  294. }
  295. }
  296. }
  297. }
  298. }
  299. CSTRING_CATCH
  300. {
  301. return FALSE;
  302. }
  303. return TRUE;
  304. }
  305. BOOL
  306. NOTIFY_FUNCTION(
  307. DWORD fdwReason)
  308. {
  309. BOOL bSuccess = TRUE;
  310. if (fdwReason == DLL_PROCESS_ATTACH)
  311. {
  312. // Run the command line to check for adjustments to defaults
  313. bSuccess = ParseCommandLine(COMMAND_LINE);
  314. }
  315. return bSuccess;
  316. }
  317. /*++
  318. Register hooked functions
  319. --*/
  320. HOOK_BEGIN
  321. CALL_NOTIFY_FUNCTION
  322. APIHOOK_ENTRY_DIRECTX_COMSERVER()
  323. COMHOOK_ENTRY(DirectDraw, IDirectDraw, CreateSurface, 6)
  324. COMHOOK_ENTRY(DirectDraw, IDirectDraw2, CreateSurface, 6)
  325. COMHOOK_ENTRY(DirectDraw, IDirectDraw4, CreateSurface, 6)
  326. COMHOOK_ENTRY(DirectDraw, IDirectDraw7, CreateSurface, 6)
  327. HOOK_END
  328. IMPLEMENT_SHIM_END