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.

358 lines
9.7 KiB

  1. #include "stdafx.h"
  2. #include "Ctrl.h"
  3. #include "OldExtension.h"
  4. /***************************************************************************\
  5. *****************************************************************************
  6. *
  7. * class OldExtension
  8. *
  9. *****************************************************************************
  10. \***************************************************************************/
  11. static const GUID guidAysncDestroy = { 0xbfe02331, 0xc17d, 0x45ea, { 0x96, 0x35, 0xa0, 0x7a, 0x90, 0x37, 0xfe, 0x34 } }; // {BFE02331-C17D-45ea-9635-A07A9037FE34}
  12. MSGID OldExtension::s_msgidAsyncDestroy = 0;
  13. /***************************************************************************\
  14. *
  15. * OldExtension::~OldExtension
  16. *
  17. * ~OldExtension() checks that resources were properly cleaned up before the
  18. * OldExtension was destroyed.
  19. *
  20. \***************************************************************************/
  21. OldExtension::~OldExtension()
  22. {
  23. //
  24. // Ensure proper destruction
  25. //
  26. AssertMsg(m_hgadListen == NULL, "Gadget should already be destroyed");
  27. }
  28. /***************************************************************************\
  29. *
  30. * OldExtension::Create
  31. *
  32. * Create() initializes a new OldExtension and attaches it to the subject Gadget
  33. * being modified.
  34. *
  35. \***************************************************************************/
  36. HRESULT
  37. OldExtension::Create(
  38. IN HGADGET hgadSubject, // Gadget being "extended"
  39. IN const GUID * pguid, // Unique ID of OldExtension
  40. IN OUT PRID * pprid, // Short ID for OldExtension
  41. IN UINT nOptions) // Options
  42. {
  43. AssertWritePtr(pprid);
  44. //
  45. // Do not allow attaching a OldExtension to a Gadget that has already started
  46. // the destruction process.
  47. //
  48. BOOL fStartDelete;
  49. if ((!IsStartDelete(hgadSubject, &fStartDelete)) || fStartDelete) {
  50. return DU_E_STARTDESTROY;
  51. }
  52. //
  53. // Setup information necessary for asynchronous destruction.
  54. //
  55. m_fAsyncDestroy = TestFlag(nOptions, oAsyncDestroy);
  56. if (m_fAsyncDestroy) {
  57. if (s_msgidAsyncDestroy == 0) {
  58. s_msgidAsyncDestroy = RegisterGadgetMessage(&guidAysncDestroy);
  59. if (s_msgidAsyncDestroy == 0) {
  60. return (HRESULT) GetLastError();
  61. }
  62. }
  63. }
  64. //
  65. // Determine if this OldExtension is already attached to the Gadget being
  66. // extended.
  67. //
  68. if (*pprid == 0) {
  69. *pprid = RegisterGadgetProperty(pguid);
  70. if (*pprid == 0) {
  71. return GetLastError();
  72. }
  73. }
  74. PRID prid = *pprid;
  75. OldExtension * pbExist;
  76. if (GetGadgetProperty(hgadSubject, prid, (void **) &pbExist) != NULL) {
  77. if (TestFlag(nOptions, oUseExisting)) {
  78. return DU_S_ALREADYEXISTS;
  79. } else {
  80. //
  81. // Already attached, but can't use the existing one. We need to
  82. // remove the existing OldExtension before attaching the new one. After
  83. // calling RemoveExisting(), the OldExtension should no longer be
  84. // attached to the Gadget.
  85. //
  86. pbExist->OnRemoveExisting();
  87. Assert(!GetGadgetProperty(hgadSubject, prid, (void **) &pbExist));
  88. }
  89. }
  90. //
  91. // Setup a listener to be notifyed when the RootGadget is destroyed.
  92. //
  93. HRESULT hr = S_OK;
  94. m_hgadListen = CreateGadget(NULL, GC_MESSAGE, ListenProc, this);
  95. if (m_hgadListen == NULL) {
  96. hr = E_OUTOFMEMORY;
  97. goto Error;
  98. }
  99. m_hgadSubject = hgadSubject;
  100. m_pridListen = prid;
  101. if (!SetGadgetProperty(hgadSubject, prid, this) ||
  102. (!AddGadgetMessageHandler(hgadSubject, GM_DESTROY, m_hgadListen))) {
  103. DeleteObject(m_hgadListen);
  104. m_hgadListen = NULL;
  105. hr = E_OUTOFMEMORY;
  106. goto Error;
  107. }
  108. //
  109. // Successfully created the OldExtension
  110. //
  111. return S_OK;
  112. Error:
  113. Destroy();
  114. return hr;
  115. }
  116. /***************************************************************************\
  117. *
  118. * OldExtension::Destroy
  119. *
  120. * Destroy() is called from the derived class to cleanup resources associated
  121. * with the OldExtension.
  122. *
  123. \***************************************************************************/
  124. void
  125. OldExtension::Destroy()
  126. {
  127. //
  128. // Since the OldExtension is being destroyed, need to ensure that it is no
  129. // longer "attached" to the Gadget being extended
  130. //
  131. if ((m_pridListen != 0) && (m_hgadSubject != NULL)) {
  132. OldExtension * pb;
  133. if (GetGadgetProperty(m_hgadSubject, m_pridListen, (void **) &pb)) {
  134. if (pb == this) {
  135. RemoveGadgetProperty(m_hgadSubject, m_pridListen);
  136. }
  137. }
  138. }
  139. if (m_hgadListen != NULL) {
  140. ::DeleteHandle(m_hgadListen);
  141. m_hgadListen = NULL;
  142. }
  143. }
  144. /***************************************************************************\
  145. *
  146. * OldExtension::DeleteHandle
  147. *
  148. * DeleteHandle() starts the destruction process for the OldExtension.
  149. *
  150. \***************************************************************************/
  151. void
  152. OldExtension::DeleteHandle()
  153. {
  154. if (m_hgadListen != NULL) {
  155. HGADGET hgad = m_hgadListen;
  156. m_hgadListen = NULL;
  157. ::DeleteHandle(hgad);
  158. }
  159. }
  160. /***************************************************************************\
  161. *
  162. * OldExtension::ListenProc
  163. *
  164. * ListenProc() is called on the MessageGadget Listener attached to the
  165. * RootGadget.
  166. *
  167. \***************************************************************************/
  168. HRESULT
  169. OldExtension::ListenProc(HGADGET hgadCur, void * pvCur, EventMsg * pmsg)
  170. {
  171. UNREFERENCED_PARAMETER(hgadCur);
  172. OldExtension * pb = (OldExtension *) pvCur;
  173. switch (GET_EVENT_DEST(pmsg))
  174. {
  175. case GMF_DIRECT:
  176. if (pmsg->nMsg == GM_DESTROY) {
  177. GMSG_DESTROY * pmsgD = (GMSG_DESTROY *) pmsg;
  178. if (pmsgD->nCode == GDESTROY_FINAL) {
  179. pb->OnDestroyListener();
  180. return DU_S_PARTIAL;
  181. }
  182. } else if (pb->m_fAsyncDestroy && (pmsg->nMsg == s_msgidAsyncDestroy)) {
  183. pb->OnAsyncDestroy();
  184. return DU_S_PARTIAL;
  185. }
  186. break;
  187. case GMF_EVENT:
  188. if (pmsg->nMsg == GM_DESTROY) {
  189. if (((GMSG_DESTROY *) pmsg)->nCode == GDESTROY_FINAL) {
  190. pb->OnDestroySubject();
  191. return DU_S_PARTIAL;
  192. }
  193. }
  194. break;
  195. }
  196. return DU_S_NOTHANDLED;
  197. }
  198. /***************************************************************************\
  199. *
  200. * OldExtension::OnRemoveExisting
  201. *
  202. * OnRemoveExisting() is called when creating a new OldExtension to remove an
  203. * existing OldExtension already attached to the subject Gadget.
  204. *
  205. \***************************************************************************/
  206. void
  207. OldExtension::OnRemoveExisting()
  208. {
  209. }
  210. /***************************************************************************\
  211. *
  212. * OldExtension::OnDestroySubject
  213. *
  214. * OnDestroySubject() notifies the derived OldExtension that the subject Gadget
  215. * being modified has been destroyed.
  216. *
  217. \***************************************************************************/
  218. void
  219. OldExtension::OnDestroySubject()
  220. {
  221. }
  222. /***************************************************************************\
  223. *
  224. * OldExtension::OnDestroyListener
  225. *
  226. * OnDestroyListener() notifies the derived OldExtension that the internal
  227. * "Listener" Gadget has been destroyed and that the OldExtension should start
  228. * its destruction process.
  229. *
  230. \***************************************************************************/
  231. void
  232. OldExtension::OnDestroyListener()
  233. {
  234. }
  235. /***************************************************************************\
  236. *
  237. * OldExtension::OnAsyncDestroy
  238. *
  239. * OnAsyncDestroy() is called when the OldExtension receives an asynchronous
  240. * destruction message that was previously posted. This provides the derived
  241. * OldExtension an opportunity to start the destruction process without being
  242. * nested several levels.
  243. *
  244. \***************************************************************************/
  245. void
  246. OldExtension::OnAsyncDestroy()
  247. {
  248. }
  249. /***************************************************************************\
  250. *
  251. * OldExtension::PostAsyncDestroy
  252. *
  253. * PostAsyncDestroy() queues an asynchronous destruction message. This
  254. * provides the derived OldExtension an opportunity to start the destruction
  255. * process without being nested several levels.
  256. *
  257. \***************************************************************************/
  258. void
  259. OldExtension::PostAsyncDestroy()
  260. {
  261. AssertMsg(m_fAsyncDestroy,
  262. "Must create OldExtension with oAsyncDestroy if want to destroy asynchronously");
  263. Assert(s_msgidAsyncDestroy != 0);
  264. AssertMsg(m_hgadListen, "Must still have a valid Listener");
  265. EventMsg msg;
  266. ZeroMemory(&msg, sizeof(msg));
  267. msg.cbSize = sizeof(msg);
  268. msg.hgadMsg = m_hgadListen;
  269. msg.nMsg = s_msgidAsyncDestroy;
  270. DUserPostEvent(&msg, 0);
  271. }
  272. /***************************************************************************\
  273. *
  274. * OldExtension::GetExtension
  275. *
  276. * GetExtension() retrieves the OldExtension of a specific type currently
  277. * attached to the subject Gadget.
  278. *
  279. \***************************************************************************/
  280. OldExtension *
  281. OldExtension::GetExtension(HGADGET hgadSubject, PRID prid)
  282. {
  283. OldExtension * pbExist;
  284. if (GetGadgetProperty(hgadSubject, prid, (void **) &pbExist)) {
  285. AssertMsg(pbExist != NULL, "Attached OldExtension must be valid");
  286. return pbExist;
  287. }
  288. return NULL;
  289. }