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.

138 lines
3.2 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000.
  5. //
  6. // File: C O N T A I N E R . C P P
  7. //
  8. // Contents:
  9. //
  10. // Notes:
  11. //
  12. // Author: mbend 6 Sep 2000
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "ucbase.h"
  18. #include "hostp.h"
  19. #include "Container.h"
  20. #include "ComUtility.h"
  21. HANDLE CContainer::s_hThreadShutdown = INVALID_HANDLE_VALUE;
  22. HANDLE CContainer::s_hEventShutdown = INVALID_HANDLE_VALUE;
  23. HANDLE CContainer::s_hProcessDiedWait = INVALID_HANDLE_VALUE;
  24. HANDLE CContainer::s_hParentProc = INVALID_HANDLE_VALUE;
  25. CContainer::CContainer()
  26. {
  27. }
  28. CContainer::~CContainer()
  29. {
  30. }
  31. STDMETHODIMP CContainer::CreateInstance(
  32. /*[in]*/ REFCLSID clsid,
  33. /*[in]*/ REFIID riid,
  34. /*[out, iid_is(riid)]*/ void ** ppv)
  35. {
  36. HRESULT hr = S_OK;
  37. hr = HrCoCreateInstanceInprocBase(clsid, riid, ppv);
  38. TraceHr(ttidError, FAL, hr, FALSE, "CContainer::CreateInstance");
  39. return hr;
  40. }
  41. STDMETHODIMP CContainer::Shutdown()
  42. {
  43. HRESULT hr = S_OK;
  44. s_hEventShutdown = CreateEvent(NULL, TRUE, FALSE, NULL);
  45. if(INVALID_HANDLE_VALUE == s_hEventShutdown)
  46. {
  47. hr = HrFromLastWin32Error();
  48. }
  49. if(SUCCEEDED(hr))
  50. {
  51. s_hThreadShutdown = CreateThread(NULL, 0, &CContainer::ShutdownThread, NULL, 0, NULL);
  52. if(INVALID_HANDLE_VALUE == s_hThreadShutdown)
  53. {
  54. hr = HrFromLastWin32Error();
  55. }
  56. }
  57. TraceHr(ttidError, FAL, hr, FALSE, "CContainer::Shutdown");
  58. return hr;
  59. }
  60. STDMETHODIMP CContainer::SetParent(DWORD pid)
  61. {
  62. HANDLE hParent;
  63. HANDLE hWait = INVALID_HANDLE_VALUE;
  64. HRESULT hr = S_OK;
  65. hParent = OpenProcess(SYNCHRONIZE, FALSE, pid);
  66. if (hParent)
  67. {
  68. if (INVALID_HANDLE_VALUE == InterlockedCompareExchangePointer(
  69. &s_hParentProc, hParent, INVALID_HANDLE_VALUE))
  70. {
  71. // we haven't created a kill thread yet
  72. if (!RegisterWaitForSingleObject(&s_hProcessDiedWait, hParent,
  73. &CContainer::KillThread, NULL, INFINITE, WT_EXECUTEONLYONCE))
  74. {
  75. hr = E_FAIL;
  76. s_hProcessDiedWait = INVALID_HANDLE_VALUE;
  77. s_hParentProc = INVALID_HANDLE_VALUE;
  78. CloseHandle(hParent);
  79. }
  80. }
  81. else
  82. {
  83. // we've already create the kill thread
  84. CloseHandle(hParent);
  85. }
  86. }
  87. else
  88. {
  89. hr = HrFromLastWin32Error();
  90. }
  91. return hr;
  92. }
  93. void CContainer::DoNormalShutdown()
  94. {
  95. SetEvent(s_hEventShutdown);
  96. WaitForSingleObject(s_hThreadShutdown, 500);
  97. CloseHandle(s_hThreadShutdown);
  98. }
  99. DWORD WINAPI CContainer::ShutdownThread(void*)
  100. {
  101. DWORD dwRet = WaitForSingleObject(s_hEventShutdown, 2000);
  102. if (s_hProcessDiedWait != INVALID_HANDLE_VALUE)
  103. {
  104. UnregisterWait(s_hProcessDiedWait);
  105. }
  106. if(WAIT_OBJECT_0 == dwRet)
  107. {
  108. CloseHandle(s_hEventShutdown);
  109. }
  110. else
  111. {
  112. CloseHandle(s_hEventShutdown);
  113. CloseHandle(s_hThreadShutdown);
  114. ExitProcess(-1);
  115. }
  116. return 0;
  117. }
  118. VOID WINAPI CContainer::KillThread(void*, BOOLEAN bTimedOut)
  119. {
  120. ExitProcess(-1);
  121. }