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