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.

112 lines
2.4 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. EmulateBitmapStride.cpp
  5. Abstract:
  6. When GetObjectA is called, modify the returned width of scan lines
  7. so that it is DWORD aligned for Bitmaps. This is a bug in GetObjectA
  8. that will be fixed in whistler, but this shim is still needed for
  9. win2k.
  10. If a program is using the width of scan lines to determine if the bitmap
  11. is mono, 16, 24 bit, etc... it may cause the program to incorrectly display
  12. the bitmap. Symptoms will be a skewed bitmap with colors shifted.
  13. Notes:
  14. This is a general purpose shim.
  15. This bug is fixed in Whistler, so this shim is for Win2k.
  16. History:
  17. 10/16/2000 mnikkel Created
  18. --*/
  19. #include "precomp.h"
  20. IMPLEMENT_SHIM_BEGIN(EmulateBitmapStride)
  21. #include "ShimHookMacro.h"
  22. APIHOOK_ENUM_BEGIN
  23. APIHOOK_ENUM_ENTRY(GetObjectA)
  24. APIHOOK_ENUM_END
  25. /*++
  26. Hook GetObjectA and align the stride if required.
  27. --*/
  28. int
  29. APIHOOK(GetObjectA)(
  30. HGDIOBJ hgdiobj, // handle to graphics object
  31. int cbBuffer, // size of buffer for object information
  32. LPVOID lpvObject // buffer for object information
  33. )
  34. {
  35. int iRet= 0;
  36. iRet = ORIGINAL_API(GetObjectA)(
  37. hgdiobj,
  38. cbBuffer,
  39. lpvObject);
  40. // If the call failed or the object is not a bitmap, pass through
  41. if (iRet != 0 &&
  42. GetObjectType(hgdiobj) == OBJ_BITMAP &&
  43. lpvObject != NULL)
  44. {
  45. BITMAP *pBitmap;
  46. LONG lOrgSize, lSizeMod;
  47. // Check to see if the is a compatible bitmap or a DIB
  48. if (cbBuffer == sizeof(BITMAP))
  49. {
  50. pBitmap= (PBITMAP)lpvObject;
  51. }
  52. else
  53. {
  54. pBitmap= &(((PDIBSECTION)lpvObject)->dsBm);
  55. }
  56. // Check the width of scan lines to see if it is DWORD aligned
  57. lOrgSize = pBitmap->bmWidthBytes;
  58. lSizeMod = 4 - (lOrgSize & 3);
  59. if (lSizeMod == 4)
  60. {
  61. lSizeMod = 0;
  62. }
  63. // If a change is necessary mod the size and log it.
  64. if (lSizeMod > 0)
  65. {
  66. pBitmap->bmWidthBytes += lSizeMod;
  67. LOGN( eDbgLevelInfo, "[GetObjectA] width of scan lines from %d to %d",
  68. lOrgSize, pBitmap->bmWidthBytes );
  69. }
  70. }
  71. return iRet;
  72. }
  73. /*++
  74. Register hooked functions
  75. --*/
  76. HOOK_BEGIN
  77. APIHOOK_ENTRY(GDI32.DLL, GetObjectA)
  78. HOOK_END
  79. IMPLEMENT_SHIM_END