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.

161 lines
3.9 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. WordPerfect9_2.cpp
  5. Abstract:
  6. WORDPERFECT 9 - GRAMMAR CHECK BUG:
  7. Shim prevents an internal reference count used by the Grammar Checker
  8. from becoming negative by not allowing Add/Release to be called more than
  9. once for the life of the interface.
  10. This COM Interface allocates some internal memory in DllGetClassObject()
  11. and frees the memory in the Release().
  12. Under WIN98 and NT4 this works because DllGetClassObject() is called at
  13. the beginning of Grammar Checking and Release() is called after completion.
  14. In Whistler OLE makes two pairs of extra calls (AddRef => Release &
  15. QueryInterface => Release) causing Release() to free the internal
  16. memory before the object is truly deleted. The code also set the internal
  17. reference count to -2. On the next initiation of the grammar checker the
  18. internal REF count NZ (-2) and DllGetClassObject() does not allocate the
  19. needed memory and then access violates.
  20. Notes:
  21. This is an application specific shim.
  22. History:
  23. 12/01/2000 a-larrsh Created
  24. --*/
  25. #include "precomp.h"
  26. #include <initguid.h>
  27. IMPLEMENT_SHIM_BEGIN(WordPerfect9_2)
  28. #include "ShimHookMacro.h"
  29. APIHOOK_ENUM_BEGIN
  30. APIHOOK_ENUM_ENTRY(DllGetClassObject)
  31. APIHOOK_ENUM_ENTRY_COMSERVER(wt9li)
  32. APIHOOK_ENUM_END
  33. IMPLEMENT_COMSERVER_HOOK(wt9li)
  34. /* ++
  35. COM definitions for object we are hooking
  36. --*/
  37. class __declspec(uuid("C0E10005-0500-0900-C0E1-C0E1C0E1C0E1")) WP9;
  38. struct __declspec(uuid("C0E10005-0100-0900-C0E1-C0E1C0E1C0E1")) IWP9;
  39. DEFINE_GUID(CLSID_WP9, 0xC0E10005, 0x0500, 0x0900, 0xC0, 0xE1, 0xC0, 0xE1, 0xC0, 0xE1, 0xC0, 0xE1);
  40. DEFINE_GUID(IID_IWP9, 0xC0E10005, 0x0100, 0x0900, 0xC0, 0xE1, 0xC0, 0xE1, 0xC0, 0xE1, 0xC0, 0xE1);
  41. typedef HRESULT (*_pfn_IWP9_QueryInterface)( PVOID pThis, REFIID iid, PVOID* ppvObject );
  42. typedef ULONG (*_pfn_IWP9_AddRef)( PVOID pThis );
  43. typedef ULONG (*_pfn_IWP9_Release)( PVOID pThis );
  44. /*++
  45. Manage OLE Object Ref count for QueryInterface, AddRef and Release
  46. --*/
  47. static int g_nInternalRefCount = 0;
  48. HRESULT
  49. APIHOOK(DllGetClassObject)(REFCLSID rclsid, REFIID riid, LPVOID * ppv)
  50. {
  51. HRESULT hrResult;
  52. hrResult = ORIGINAL_API(DllGetClassObject)(rclsid, riid, ppv);
  53. if ( IsEqualGUID(rclsid, CLSID_WP9) &&
  54. IsEqualGUID(riid, IID_IWP9) &&
  55. hrResult == S_OK)
  56. {
  57. if (g_nInternalRefCount == 0)
  58. {
  59. g_nInternalRefCount++;
  60. }
  61. DPFN( eDbgLevelInfo, "DllGetClassObject");
  62. }
  63. return hrResult;
  64. }
  65. ULONG
  66. COMHOOK(IWP9, AddRef)(PVOID pThis)
  67. {
  68. if (g_nInternalRefCount == 0)
  69. {
  70. _pfn_IWP9_AddRef pfnAddRef = (_pfn_IWP9_AddRef) ORIGINAL_COM(IWP9, AddRef, pThis);
  71. (*pfnAddRef)(pThis);
  72. }
  73. g_nInternalRefCount++;
  74. DPFN( eDbgLevelInfo, "AddRef");
  75. return g_nInternalRefCount;
  76. }
  77. ULONG
  78. COMHOOK(IWP9, Release)(PVOID pThis)
  79. {
  80. g_nInternalRefCount--;
  81. if (g_nInternalRefCount == 0)
  82. {
  83. _pfn_IWP9_Release pfnRelease = (_pfn_IWP9_Release) ORIGINAL_COM(IWP9, Release, pThis);
  84. (*pfnRelease)(pThis);
  85. }
  86. DPFN( eDbgLevelInfo, "Release");
  87. return g_nInternalRefCount;
  88. }
  89. HRESULT
  90. COMHOOK(IWP9, QueryInterface)( PVOID pThis, REFIID iid, PVOID* ppvObject )
  91. {
  92. HRESULT hrResult;
  93. _pfn_IWP9_QueryInterface pfnQueryInterface = (_pfn_IWP9_QueryInterface) ORIGINAL_COM(IWP9, QueryInterface, pThis);
  94. hrResult = (*pfnQueryInterface)(pThis, iid, ppvObject);
  95. DPFN( eDbgLevelInfo, "QueryInterface");
  96. return hrResult;
  97. }
  98. /*++
  99. Register hooked functions
  100. --*/
  101. HOOK_BEGIN
  102. APIHOOK_ENTRY_COMSERVER(wt9li)
  103. APIHOOK_ENTRY(wt9li.dll, DllGetClassObject)
  104. COMHOOK_ENTRY(WP9, IWP9, QueryInterface, 0)
  105. COMHOOK_ENTRY(WP9, IWP9, AddRef, 1)
  106. COMHOOK_ENTRY(WP9, IWP9, Release, 2)
  107. HOOK_END
  108. IMPLEMENT_SHIM_END