124 lines
4.5 KiB
C
124 lines
4.5 KiB
C
|
#pragma option push -b -a8 -pc -A- /*P_O_Push*/
|
||
|
//// bpcsuspend.h - header file for interface that allows external apps
|
||
|
// to request that the bpc video server release all of its devices and
|
||
|
// shutdown its directshow graph.
|
||
|
|
||
|
// USAGE:
|
||
|
// in order to request that the bpc subsystem release its devices
|
||
|
// create an instance of the CBPCSuspend class
|
||
|
// to check if this succeeded use the IsBPCSuspended member function. if IsBPCSuspended returns false
|
||
|
// then that means that there are active bpc video clients and you must treat this as you would a
|
||
|
// device busy or device open type of failure.
|
||
|
// when you are done with the devices destroy the CBPCSuspend class and this will notify vidsvr
|
||
|
// that it can resume using the devices and return to background data capturing
|
||
|
//
|
||
|
// NOTE: you must compile vidsvr.odl and include the resulting .h before including this file
|
||
|
// NOTE: you must have initialized com prior on this thread prior to using this object.
|
||
|
//
|
||
|
// CLSID_BPCSuspend comes from the header file generated from compiling vidsvr.odl
|
||
|
// IBPCSuspended comes from the header file generated from compiling vidsvr.odl
|
||
|
|
||
|
// theory of operation:
|
||
|
// by using GetActiveObject instead of CoCreateInstance we don't force vidsvr to be loaded just to find
|
||
|
// out that it wasn't running in the first place.
|
||
|
// by returning an object that must be released to free the devices so that vidsvr can continue background
|
||
|
// data capture we utilize COM to manage this resource. this means that if the external app that requested
|
||
|
// the devices crashes or leaks then the suspension object will be automatically released and
|
||
|
// vidsvr can resume using the devices without requiring a system reboot or some other unfriendly intervention.
|
||
|
|
||
|
#ifndef _MSBPCVideo_H_
|
||
|
#error you must include the .h generated from compiling vidsvr.odl before including this file
|
||
|
#endif
|
||
|
|
||
|
#ifndef BPCSUSP_H
|
||
|
#define BPCSUSP_H
|
||
|
#pragma once
|
||
|
|
||
|
#include <oleauto.h>
|
||
|
|
||
|
#ifdef _CPPUNWIND
|
||
|
#pragma message("bpcsusp.h using exceptions")
|
||
|
#define BPCTRY try {
|
||
|
#ifdef _DEBUG
|
||
|
#define BPCCATCH } catch(...) { OutputDebugString("CBPCSuspend exception\r\n");}
|
||
|
#else
|
||
|
#define BPCCATCH } catch(...) {}
|
||
|
#endif
|
||
|
#define BPCNOTHROW throw()
|
||
|
#else
|
||
|
#define BPCTRY
|
||
|
#define BPCCATCH
|
||
|
#define BPCNOTHROW
|
||
|
#endif
|
||
|
|
||
|
class CBPCSuspend {
|
||
|
IDispatch* m_pSuspended;
|
||
|
bool m_fBPCExists;
|
||
|
public:
|
||
|
inline CBPCSuspend() BPCNOTHROW : m_pSuspended(NULL), m_fBPCExists(false) {
|
||
|
BPCTRY
|
||
|
#ifdef _DEBUG
|
||
|
OutputDebugString("CBPCSuspend()::CBPCSuspend()\r\n");
|
||
|
TCHAR msgtemp[256];
|
||
|
#endif
|
||
|
IUnknown *pUnkSuspendor = NULL;
|
||
|
DWORD dwReserved;
|
||
|
HRESULT hr = GetActiveObject(CLSID_BPCSuspend, &dwReserved, &pUnkSuspendor);
|
||
|
if (SUCCEEDED(hr) && pUnkSuspendor) {
|
||
|
IBPCSuspend *pSuspendor = NULL;
|
||
|
hr = pUnkSuspendor->QueryInterface(IID_IBPCSuspend, reinterpret_cast<void **>(&pSuspendor));
|
||
|
pUnkSuspendor->Release();
|
||
|
if (SUCCEEDED(hr) && pSuspendor) {
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
OutputDebugString("CBPCSuspend()::CBPCSuspend() BPC exists\r\n");
|
||
|
#endif
|
||
|
m_fBPCExists = true;
|
||
|
hr = pSuspendor->DeviceRelease(0L, &m_pSuspended);
|
||
|
if (FAILED(hr) || !m_pSuspended) {
|
||
|
#ifdef _DEBUG
|
||
|
wsprintf(msgtemp, "CBPCSuspend()::CBPCSuspend() Suspendor->DeviceRelease() rc = %lx\r\n", hr);
|
||
|
OutputDebugString(msgtemp);
|
||
|
#endif
|
||
|
ASSERT(!m_pSuspended);
|
||
|
}
|
||
|
#ifdef _DEBUG
|
||
|
else {
|
||
|
wsprintf(msgtemp, "CBPCSuspend()::CBPCSuspend() BPC video server suspended\r\n");
|
||
|
OutputDebugString(msgtemp);
|
||
|
}
|
||
|
#endif
|
||
|
pSuspendor->Release();
|
||
|
}
|
||
|
|
||
|
|
||
|
} else {
|
||
|
#ifdef _DEBUG
|
||
|
wsprintf(msgtemp, "CBPCSuspend()::CBPCSuspend() GetActiveObject() rc = %lx\r\n", hr);
|
||
|
OutputDebugString(msgtemp);
|
||
|
#endif
|
||
|
}
|
||
|
BPCCATCH
|
||
|
}
|
||
|
inline ~CBPCSuspend() BPCNOTHROW {
|
||
|
BPCTRY
|
||
|
if (m_fBPCExists && m_pSuspended) {
|
||
|
m_pSuspended->Release();
|
||
|
m_pSuspended = NULL;
|
||
|
}
|
||
|
BPCCATCH
|
||
|
}
|
||
|
inline bool IsBPCSuspended() BPCNOTHROW {
|
||
|
// if m_fBPCExists but we weren't able to retrieve a suspension object then
|
||
|
// there are active video clients and you must treat this as a device busy/failed to open type error
|
||
|
if (m_fBPCExists && !m_pSuspended) {
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#endif
|
||
|
// end of file - bpcsusp.h
|
||
|
#pragma option pop /*P_O_Pop*/
|