mirror of https://github.com/tongzx/nt5src
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
138 lines
3.2 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 2000.
|
|
//
|
|
// File: C O N T A I N E R . C P P
|
|
//
|
|
// Contents:
|
|
//
|
|
// Notes:
|
|
//
|
|
// Author: mbend 6 Sep 2000
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
|
|
#include "ucbase.h"
|
|
#include "hostp.h"
|
|
#include "Container.h"
|
|
#include "ComUtility.h"
|
|
|
|
HANDLE CContainer::s_hThreadShutdown = INVALID_HANDLE_VALUE;
|
|
HANDLE CContainer::s_hEventShutdown = INVALID_HANDLE_VALUE;
|
|
HANDLE CContainer::s_hProcessDiedWait = INVALID_HANDLE_VALUE;
|
|
HANDLE CContainer::s_hParentProc = INVALID_HANDLE_VALUE;
|
|
|
|
CContainer::CContainer()
|
|
{
|
|
}
|
|
|
|
CContainer::~CContainer()
|
|
{
|
|
}
|
|
|
|
STDMETHODIMP CContainer::CreateInstance(
|
|
/*[in]*/ REFCLSID clsid,
|
|
/*[in]*/ REFIID riid,
|
|
/*[out, iid_is(riid)]*/ void ** ppv)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = HrCoCreateInstanceInprocBase(clsid, riid, ppv);
|
|
|
|
TraceHr(ttidError, FAL, hr, FALSE, "CContainer::CreateInstance");
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CContainer::Shutdown()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
s_hEventShutdown = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
if(INVALID_HANDLE_VALUE == s_hEventShutdown)
|
|
{
|
|
hr = HrFromLastWin32Error();
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
s_hThreadShutdown = CreateThread(NULL, 0, &CContainer::ShutdownThread, NULL, 0, NULL);
|
|
if(INVALID_HANDLE_VALUE == s_hThreadShutdown)
|
|
{
|
|
hr = HrFromLastWin32Error();
|
|
}
|
|
}
|
|
|
|
TraceHr(ttidError, FAL, hr, FALSE, "CContainer::Shutdown");
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CContainer::SetParent(DWORD pid)
|
|
{
|
|
HANDLE hParent;
|
|
HANDLE hWait = INVALID_HANDLE_VALUE;
|
|
HRESULT hr = S_OK;
|
|
hParent = OpenProcess(SYNCHRONIZE, FALSE, pid);
|
|
|
|
if (hParent)
|
|
{
|
|
if (INVALID_HANDLE_VALUE == InterlockedCompareExchangePointer(
|
|
&s_hParentProc, hParent, INVALID_HANDLE_VALUE))
|
|
{
|
|
// we haven't created a kill thread yet
|
|
if (!RegisterWaitForSingleObject(&s_hProcessDiedWait, hParent,
|
|
&CContainer::KillThread, NULL, INFINITE, WT_EXECUTEONLYONCE))
|
|
{
|
|
hr = E_FAIL;
|
|
s_hProcessDiedWait = INVALID_HANDLE_VALUE;
|
|
s_hParentProc = INVALID_HANDLE_VALUE;
|
|
CloseHandle(hParent);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// we've already create the kill thread
|
|
CloseHandle(hParent);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = HrFromLastWin32Error();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
void CContainer::DoNormalShutdown()
|
|
{
|
|
SetEvent(s_hEventShutdown);
|
|
WaitForSingleObject(s_hThreadShutdown, 500);
|
|
CloseHandle(s_hThreadShutdown);
|
|
}
|
|
|
|
DWORD WINAPI CContainer::ShutdownThread(void*)
|
|
{
|
|
DWORD dwRet = WaitForSingleObject(s_hEventShutdown, 2000);
|
|
if (s_hProcessDiedWait != INVALID_HANDLE_VALUE)
|
|
{
|
|
UnregisterWait(s_hProcessDiedWait);
|
|
}
|
|
if(WAIT_OBJECT_0 == dwRet)
|
|
{
|
|
CloseHandle(s_hEventShutdown);
|
|
}
|
|
else
|
|
{
|
|
CloseHandle(s_hEventShutdown);
|
|
CloseHandle(s_hThreadShutdown);
|
|
ExitProcess(-1);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
VOID WINAPI CContainer::KillThread(void*, BOOLEAN bTimedOut)
|
|
{
|
|
ExitProcess(-1);
|
|
}
|