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

//+---------------------------------------------------------------------------
//
// 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);
}