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.

252 lines
7.4 KiB

  1. /***************************************************************************\
  2. *
  3. * File: MsgObject.cpp
  4. *
  5. * Description:
  6. * MsgObject.cpp implements the "Message Object" class that is used to receive
  7. * messages in DirectUser. This object is created for each instance of a
  8. * class that is instantiated.
  9. *
  10. *
  11. * History:
  12. * 8/05/2000: JStall: Created
  13. *
  14. * Copyright (C) 2000 by Microsoft Corporation. All rights reserved.
  15. *
  16. \***************************************************************************/
  17. #include "stdafx.h"
  18. #include "Msg.h"
  19. #include "MsgObject.h"
  20. #include "MsgTable.h"
  21. #include "MsgClass.h"
  22. /***************************************************************************\
  23. *****************************************************************************
  24. *
  25. * class MsgObject
  26. *
  27. *****************************************************************************
  28. \***************************************************************************/
  29. /***************************************************************************\
  30. *
  31. * MsgObject::xwDestroy
  32. *
  33. * xwDestroy() is called when the object reaches the final xwUnlock(), giving
  34. * the MsgObject a chance to hook into properly tear-down the external object.
  35. *
  36. \***************************************************************************/
  37. void
  38. MsgObject::xwDestroy()
  39. {
  40. xwEndDestroy();
  41. BaseObject::xwDestroy();
  42. }
  43. /***************************************************************************\
  44. *
  45. * MsgObject::xwEndDestroy
  46. *
  47. * xwEndDestroy() ends the destruction process for a given MsgObject to free
  48. * its associated resources. This includes destroying all child Gadgets in
  49. * the subtree before this Gadget is destroyed.
  50. *
  51. * Any class that derives from MsgObject and overrides xwDestroy() without
  52. * calling MsgObject::xwDestroy() MUST call xwEndDestroy(). This allows
  53. * derived classes to use special pool allocators, but still properly
  54. * tear down the "attached" objects.
  55. *
  56. \***************************************************************************/
  57. void
  58. MsgObject::xwEndDestroy()
  59. {
  60. if (m_emo.m_pmt != NULL) {
  61. //
  62. // Need to "demote" the object all of the way down.
  63. //
  64. m_emo.m_pmt->GetClass()->xwTearDownObject(this);
  65. AssertMsg(m_emo.m_arpThis.GetSize() == 0,
  66. "After TearDown, should not have any remaining 'this' pointers");
  67. #if DBG
  68. // DEBUG: Stuff pMT with a bogus value to help identify destroyed object
  69. m_emo.m_pmt = (const MsgTable *) ULongToPtr(0xA0E2A0E2);
  70. #endif
  71. }
  72. }
  73. /***************************************************************************\
  74. *
  75. * MsgObject::PromoteInternal
  76. *
  77. * PromoteInternal() provides an empty promotion function that can be used
  78. * to build internal objects. This promotion function WILL NOT actually
  79. * allocate the object and can only be used to prevent the creation of a
  80. * base class that can not be directly created.
  81. *
  82. \***************************************************************************/
  83. HRESULT CALLBACK
  84. MsgObject::PromoteInternal(
  85. IN DUser::ConstructProc pfnCS, // Creation callback function
  86. IN HCLASS hclCur, // Class to promote to
  87. IN DUser::Gadget * pgad, // Object being promoted
  88. IN DUser::Gadget::ConstructInfo * pciData) // Construction parameters
  89. {
  90. UNREFERENCED_PARAMETER(pfnCS);
  91. UNREFERENCED_PARAMETER(hclCur);
  92. UNREFERENCED_PARAMETER(pgad);
  93. UNREFERENCED_PARAMETER(pciData);
  94. //
  95. // Not allowed to directly create this object. Derived classes must provide
  96. // their own Promotion function.
  97. //
  98. return S_OK;
  99. }
  100. /***************************************************************************\
  101. *
  102. * MsgObject::DemoteInternal
  103. *
  104. * DemoteInternal() provides an empty demotion function that can be used
  105. * to tear-down internal objects. Since there is rarely anything to do for
  106. * demotion of internal objects, this demotion function may be safely used
  107. * for internal objects.
  108. *
  109. \***************************************************************************/
  110. HCLASS CALLBACK
  111. MsgObject::DemoteInternal(
  112. IN HCLASS hclCur, // Class of Gadget being destroyed
  113. IN DUser::Gadget * pgad, // Gadget being destroyed
  114. IN void * pvData) // Implementation data on object
  115. {
  116. UNREFERENCED_PARAMETER(hclCur);
  117. UNREFERENCED_PARAMETER(pgad);
  118. UNREFERENCED_PARAMETER(pvData);
  119. return NULL;
  120. }
  121. #if 1
  122. /***************************************************************************\
  123. *
  124. * MsgObject::SetupInternal
  125. *
  126. * SetupInternal() sets up an internal object that is being created as a
  127. * handle (legacy object). This function should not be called on objects
  128. * that are being created as "Gadget's".
  129. *
  130. * TODO: Try to remove this function
  131. *
  132. \***************************************************************************/
  133. BOOL
  134. MsgObject::SetupInternal(
  135. IN HCLASS hcl) // Internal class being setup
  136. {
  137. MsgClass * pmcThis = ValidateMsgClass(hcl);
  138. AssertMsg((pmcThis != NULL) && pmcThis->IsInternal(), "Must be a valid internal class");
  139. int cLevels = 0;
  140. const MsgClass * pmcCur = pmcThis;
  141. while (pmcCur != NULL) {
  142. cLevels++;
  143. pmcCur = pmcCur->GetSuper();
  144. }
  145. VerifyMsg(m_emo.m_arpThis.GetSize() == 0, "Must not already be initialized");
  146. if (!m_emo.m_arpThis.SetSize(cLevels)) {
  147. return FALSE;
  148. }
  149. for (int idx = 0; idx < cLevels; idx++) {
  150. m_emo.m_arpThis[idx] = this;
  151. }
  152. m_emo.m_pmt = pmcThis->GetMsgTable();
  153. AssertMsg(m_emo.m_pmt != NULL, "Must now have a valid MT");
  154. return TRUE;
  155. }
  156. #endif
  157. /***************************************************************************\
  158. *
  159. * MsgObject::InstanceOf
  160. *
  161. * InstanceOf() checks if the MsgObject is an "instance of" a specified class
  162. * by traversing the inheritance heirarchy.
  163. *
  164. \***************************************************************************/
  165. BOOL
  166. MsgObject::InstanceOf(
  167. IN const MsgClass * pmcTest // Class checking for instance
  168. ) const
  169. {
  170. AssertMsg(pmcTest != NULL, "Must have a valid MsgClass");
  171. const MsgClass * pmcCur = m_emo.m_pmt->GetClass();
  172. while (pmcCur != NULL) {
  173. if (pmcCur == pmcTest) {
  174. return TRUE;
  175. }
  176. pmcCur = pmcCur->GetSuper();
  177. }
  178. return FALSE;
  179. }
  180. /***************************************************************************\
  181. *
  182. * MsgObject::GetGutsData
  183. *
  184. * GetGutsData() retreives the implementation-specific data for the specified
  185. * class on the given object.
  186. *
  187. * NOTE: This operation has been highly optimized for speed and will not
  188. * validate that the object is of the specified class type. If the caller is
  189. * uncertain, they must call InstanceOf() or CastClass() to properly
  190. * determine the object's type.
  191. *
  192. \***************************************************************************/
  193. void *
  194. MsgObject::GetGutsData(
  195. IN const MsgClass * pmcData // Class of guts data
  196. ) const
  197. {
  198. #if DBG
  199. if (!InstanceOf(pmcData)) {
  200. PromptInvalid("The Gadget is not the specified class");
  201. }
  202. #endif
  203. int cDepth = pmcData->GetMsgTable()->GetDepth();
  204. #if DBG
  205. if ((cDepth < 0) || (cDepth >= m_emo.m_arpThis.GetSize())) {
  206. PromptInvalid("The Gadget does not have data for the specified class");
  207. }
  208. #endif
  209. return m_emo.m_arpThis[cDepth];
  210. }