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.

275 lines
6.2 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. EuropeanAirWar.cpp
  5. Abstract:
  6. European Air War takes advantage of the fact GDI and DDRAW affect separate
  7. palettes in win98. This causes a problem on win2k when EAW calls
  8. GetSystemPaletteEntries and expects the original GDI palette, but in win2k
  9. it has be faded to black by DDRAW. This fix restores the system palette at
  10. a convienient spot in SetSystemPaletteUse. It also sets SYSPAL_STATIC
  11. before creating dialog boxes.
  12. In addition this corrects an install problem that occurs when setting the
  13. path for the readme file in a start->programs shortcut.
  14. Notes:
  15. This is an app specific shim and should NOT be
  16. included in the layer.
  17. History:
  18. 10/23/2000 linstev Created
  19. 10/23/2000 mnikkel Modified
  20. --*/
  21. #include "precomp.h"
  22. IMPLEMENT_SHIM_BEGIN(EuropeanAirWar)
  23. #include "ShimHookMacro.h"
  24. APIHOOK_ENUM_BEGIN
  25. APIHOOK_ENUM_ENTRY(SetSystemPaletteUse)
  26. APIHOOK_ENUM_ENTRY(DialogBoxParamA)
  27. APIHOOK_ENUM_ENTRY_COMSERVER(SHELL32)
  28. APIHOOK_ENUM_END
  29. IMPLEMENT_COMSERVER_HOOK(SHELL32)
  30. CString * g_csArgBuffer = NULL;
  31. /*++
  32. Retrieve the system palette and set the palette entries flag so the palette is
  33. updated correctly.
  34. --*/
  35. UINT
  36. APIHOOK(SetSystemPaletteUse)(
  37. HDC hdc,
  38. UINT uUsage
  39. )
  40. {
  41. UINT iRet = ORIGINAL_API(SetSystemPaletteUse)(hdc, uUsage);
  42. int i;
  43. HDC hdcnew;
  44. HPALETTE hpal, hpalold;
  45. LPLOGPALETTE plogpal;
  46. // Create a palette we can realize
  47. plogpal = (LPLOGPALETTE) malloc(sizeof(LOGPALETTE) + sizeof(PALETTEENTRY)*256);
  48. if ( plogpal )
  49. {
  50. LOGN( eDbgLevelError, "[EuropeanAirWar] APIHook_SetSystemPaletteUse reseting palette");
  51. plogpal->palVersion = 0x0300;
  52. plogpal->palNumEntries = 256;
  53. hdcnew = GetDC(0);
  54. GetSystemPaletteEntries(hdcnew, 0, 256, &plogpal->palPalEntry[0]);
  55. for (i=0; i<256; i++)
  56. {
  57. plogpal->palPalEntry[i].peFlags = PC_RESERVED | PC_NOCOLLAPSE;
  58. }
  59. // Realize the palette
  60. hpal = CreatePalette(plogpal);
  61. hpalold = SelectPalette(hdcnew, hpal, FALSE);
  62. RealizePalette(hdcnew);
  63. SelectPalette(hdcnew, hpalold, FALSE);
  64. DeleteObject(hpal);
  65. ReleaseDC(0, hdcnew);
  66. free(plogpal);
  67. }
  68. else
  69. {
  70. LOGN( eDbgLevelError, "[EuropeanAirWar] APIHook_SetSystemPaletteUse failed to allocate memory");
  71. }
  72. return iRet;
  73. }
  74. /*++
  75. Set the Palette Use to static before creating a dialog box.
  76. --*/
  77. int
  78. APIHOOK(DialogBoxParamA)(
  79. HINSTANCE hInstance,
  80. LPCSTR lpTemplateName,
  81. HWND hWndParent,
  82. DLGPROC lpDialogFunc,
  83. LPARAM dwInitParam
  84. )
  85. {
  86. int iRet;
  87. HDC hdc;
  88. LOGN( eDbgLevelError, "[EuropeanAirWar] APIHook_DialogBoxParamA setting palette static for dialog box");
  89. // Set the palette use to static to prevent
  90. // any color changes in the dialog box.
  91. if (hdc = GetDC(0))
  92. {
  93. SetSystemPaletteUse(hdc, SYSPAL_STATIC);
  94. ReleaseDC(0, hdc);
  95. }
  96. iRet = ORIGINAL_API(DialogBoxParamA)(
  97. hInstance,
  98. lpTemplateName,
  99. hWndParent,
  100. lpDialogFunc,
  101. dwInitParam);
  102. // Reset the palette use to NoStatic256
  103. // after dialog box has been displayed.
  104. // use 256 to prevent white dot artifacts.
  105. if (hdc = GetDC(0))
  106. {
  107. SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC256);
  108. ReleaseDC(0, hdc);
  109. }
  110. return iRet;
  111. }
  112. /*++
  113. Catch IShellLink::SetPathA and correct the wordpad path
  114. --*/
  115. HRESULT
  116. COMHOOK(IShellLinkA, SetPath)(
  117. PVOID pThis,
  118. LPCSTR pszFile
  119. )
  120. {
  121. HRESULT hrReturn = E_FAIL;
  122. PCHAR pStr= NULL;
  123. CHAR szBuffer[MAX_PATH];
  124. _pfn_IShellLinkA_SetPath pfnOld = ORIGINAL_COM(IShellLinkA, SetPath, pThis);
  125. if ( pfnOld )
  126. {
  127. CSTRING_TRY
  128. {
  129. // pszFile = "c:\windows\wordpad.exe command line arguments"
  130. // Strip off the arguments and save them for when they call IShellLinkA::SetArguments
  131. CString csFile(pszFile);
  132. int nWordpadIndex = csFile.Find(L"wordpad.exe");
  133. if (nWordpadIndex >= 0)
  134. {
  135. // Find the first space after wordpad.exe
  136. int nSpaceIndex = csFile.Find(L' ', nWordpadIndex);
  137. if (nSpaceIndex >= 0)
  138. {
  139. // Save the cl args in g_csArgBuffer
  140. g_csArgBuffer = new CString;
  141. if (g_csArgBuffer)
  142. {
  143. csFile.Mid(nSpaceIndex, *g_csArgBuffer); // includes the space
  144. csFile.Truncate(nSpaceIndex);
  145. }
  146. }
  147. hrReturn = (*pfnOld)( pThis, csFile.GetAnsi() );
  148. return hrReturn;
  149. }
  150. }
  151. CSTRING_CATCH
  152. {
  153. // Do nothing
  154. }
  155. hrReturn = (*pfnOld)( pThis, pszFile );
  156. }
  157. return hrReturn;
  158. }
  159. /*++
  160. Catch IShellLink::SetArguments and correct the readme path.
  161. --*/
  162. HRESULT
  163. COMHOOK(IShellLinkA, SetArguments)(
  164. PVOID pThis,
  165. LPCSTR pszArgs
  166. )
  167. {
  168. HRESULT hrReturn = E_FAIL;
  169. _pfn_IShellLinkA_SetArguments pfnOld = ORIGINAL_COM(IShellLinkA, SetArguments, pThis);
  170. if (pfnOld)
  171. {
  172. if (g_csArgBuffer && !g_csArgBuffer->IsEmpty())
  173. {
  174. CSTRING_TRY
  175. {
  176. CString csArgs(pszArgs);
  177. *g_csArgBuffer += L" ";
  178. *g_csArgBuffer += csArgs;
  179. hrReturn = (*pfnOld)( pThis, g_csArgBuffer->GetAnsi() );
  180. // Delete the buffer so we don't add these args to everthing
  181. delete g_csArgBuffer;
  182. g_csArgBuffer = NULL;
  183. return hrReturn;
  184. }
  185. CSTRING_CATCH
  186. {
  187. // Do Nothing
  188. }
  189. }
  190. hrReturn = (*pfnOld)( pThis, pszArgs );
  191. }
  192. return hrReturn;
  193. }
  194. /*++
  195. Register hooked functions
  196. --*/
  197. HOOK_BEGIN
  198. APIHOOK_ENTRY(GDI32.DLL, SetSystemPaletteUse)
  199. APIHOOK_ENTRY(USER32.DLL, DialogBoxParamA)
  200. APIHOOK_ENTRY_COMSERVER(SHELL32)
  201. COMHOOK_ENTRY(ShellLink, IShellLinkA, SetPath, 20)
  202. COMHOOK_ENTRY(ShellLink, IShellLinkA, SetArguments, 11)
  203. HOOK_END
  204. IMPLEMENT_SHIM_END