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.
308 lines
6.0 KiB
308 lines
6.0 KiB
// SAFRemoteDesktopManager.cpp : Implementation of CSAFRemoteDesktopManager
|
|
#include "stdafx.h"
|
|
#include "SAFrdm.h"
|
|
#include "SAFRemoteDesktopManager.h"
|
|
|
|
//
|
|
// From HelpServiceTypeLib.idl
|
|
//
|
|
#include <HelpServiceTypeLib.h>
|
|
#include "helpservicetypelib_i.c"
|
|
|
|
#include <MPC_COM.h>
|
|
#include <MPC_utils.h>
|
|
#include <MPC_trace.h>
|
|
|
|
#define MODULE_NAME L"SAFrdm"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CSAFRemoteDesktopManager
|
|
|
|
|
|
STDMETHODIMP CSAFRemoteDesktopManager::ReserveAcceptedLock()
|
|
{
|
|
HRESULT hr=E_FAIL;
|
|
DWORD dwR;
|
|
HANDLE hMutex = NULL, hEvent = NULL;
|
|
|
|
/*
|
|
* Signal the session resolver
|
|
*/
|
|
if (!m_bstrEventName.Length() || !m_bstrMutexName.Length() )
|
|
{
|
|
// if we got here, the environment is missing our event name
|
|
// so mention it with our ret val...
|
|
hr = E_INVALIDARG;
|
|
goto done;
|
|
}
|
|
|
|
|
|
/*
|
|
* Open the handles we got from the resolver, and yank it
|
|
*/
|
|
hMutex = OpenMutex(SYNCHRONIZE, FALSE, m_bstrMutexName);
|
|
hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, m_bstrEventName);
|
|
|
|
if (!hEvent || !hMutex)
|
|
{
|
|
// only close the mutex here!
|
|
if (hMutex)
|
|
CloseHandle(hMutex);
|
|
|
|
hr = E_HANDLE;
|
|
goto done;
|
|
}
|
|
|
|
/*
|
|
* Now see if this is the first session to click "yes"
|
|
* If so, we can have the Mutex.
|
|
*/
|
|
dwR = WaitForSingleObject(hMutex, 0);
|
|
if (dwR == WAIT_OBJECT_0)
|
|
{
|
|
SetEvent(hEvent);
|
|
hr = S_OK;
|
|
m_boolAcceptReserved = TRUE;
|
|
}
|
|
else if (dwR == WAIT_ABANDONED)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else if (dwR == WAIT_TIMEOUT)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else if (dwR == WAIT_FAILED)
|
|
{
|
|
// If we didn't get the mutex, then close the handle
|
|
hr = E_ACCESSDENIED;
|
|
}
|
|
else
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
|
|
done:
|
|
// close the event handle, but NOT the mutex handle
|
|
if (hEvent)
|
|
CloseHandle(hEvent);
|
|
if (hMutex)
|
|
CloseHandle(hMutex);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSAFRemoteDesktopManager::Accepted()
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if (!m_boolAcceptReserved)
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
goto done;
|
|
}
|
|
|
|
/*
|
|
* Signal the session resolver
|
|
*/
|
|
if (!m_bstrEventName.Length())
|
|
{
|
|
// if we got here, the environment is missing our event name
|
|
// so mention it with our ret val...
|
|
hr = E_INVALIDARG;
|
|
goto done;
|
|
}
|
|
|
|
/*
|
|
* Open the handle we got from the resolver, and yank it
|
|
*/
|
|
HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, m_bstrEventName);
|
|
|
|
if (hEvent)
|
|
{
|
|
/* this is the call to the resolver that tells it we are now ready to begin RA */
|
|
SetEvent(hEvent);
|
|
hr = S_OK;
|
|
CloseHandle(hEvent);
|
|
}
|
|
else
|
|
hr = E_HANDLE;
|
|
done:
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CSAFRemoteDesktopManager::Rejected()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CSAFRemoteDesktopManager::Aborted(BSTR reason)
|
|
{
|
|
/*
|
|
* Write out an NT Event with the "reason" in it.
|
|
*/
|
|
HANDLE hEvent = RegisterEventSource(NULL, MODULE_NAME);
|
|
LPCWSTR ArgsArray[1]={reason};
|
|
|
|
if (hEvent)
|
|
{
|
|
ReportEvent(hEvent, EVENTLOG_INFORMATION_TYPE,
|
|
0,
|
|
SAFRDM_I_ABORT,
|
|
NULL,
|
|
1,
|
|
0,
|
|
ArgsArray,
|
|
NULL);
|
|
|
|
DeregisterEventSource(hEvent);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CSAFRemoteDesktopManager::SwitchDesktopMode(/*[in]*/ int nMode, /*[in]*/ int nRAType)
|
|
{
|
|
|
|
__MPC_FUNC_ENTRY(COMMONID, "CSAFRemoteDesktopManager::SwitchDesktopMode" );
|
|
|
|
|
|
HRESULT hr=E_FAIL;
|
|
CComPtr<IClassFactory> fact;
|
|
CComQIPtr<IPCHUtility> disp;
|
|
|
|
|
|
//
|
|
// This is handled in a special way.
|
|
//
|
|
// Instead of using the implementation inside HelpCtr, we QI the PCHSVC broker and then forward the call to it.
|
|
//
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, ::CoGetClassObject( CLSID_PCHService, CLSCTX_ALL, NULL, IID_IClassFactory, (void**)&fact ));
|
|
|
|
if((disp = fact))
|
|
{
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, disp->SwitchDesktopMode (nMode, nRAType));
|
|
|
|
}
|
|
else
|
|
{
|
|
__MPC_SET_ERROR_AND_EXIT(hr, E_NOINTERFACE);
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
|
|
}
|
|
|
|
STDMETHODIMP CSAFRemoteDesktopManager::get_RCTicket(BSTR *pVal)
|
|
{
|
|
|
|
if (!pVal)
|
|
return E_INVALIDARG;
|
|
|
|
*pVal = m_bstrRCTicket.Copy();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CSAFRemoteDesktopManager::get_DesktopUnknown(BOOL *pVal)
|
|
{
|
|
if (!pVal)
|
|
return E_INVALIDARG;
|
|
|
|
*pVal = m_boolDesktopUnknown;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CSAFRemoteDesktopManager::get_SupportEngineer(BSTR *pVal)
|
|
{
|
|
if (!pVal)
|
|
return E_INVALIDARG;
|
|
|
|
*pVal = m_bstrSupportEngineer.Copy();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CSAFRemoteDesktopManager::get_userHelpBlob(BSTR *pVal)
|
|
{
|
|
if (!pVal)
|
|
return E_INVALIDARG;
|
|
|
|
*pVal = m_bstruserSupportBlob.Copy();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CSAFRemoteDesktopManager::get_expertHelpBlob(BSTR *pVal)
|
|
{
|
|
if (!pVal)
|
|
return E_INVALIDARG;
|
|
|
|
*pVal = m_bstrexpertSupportBlob.Copy();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
#if 0
|
|
HRESULT CSAFRemoteDesktopManager::SignalResolver(BOOL yn)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if (yn)
|
|
{
|
|
if (!m_bstrEventName.Length())
|
|
{
|
|
// if we got here, the environment is missing our event name
|
|
// so mention it with our ret val...
|
|
hr = E_HANDLE;
|
|
goto done;
|
|
}
|
|
|
|
/*
|
|
* Open the handle we got from the resolver, and yank it
|
|
*/
|
|
HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, m_bstrEventName);
|
|
|
|
if (hEvent)
|
|
{
|
|
if (!m_boolResolverSignaled)
|
|
{
|
|
/* This is the call to tell the resolver that we WANT to start RA */
|
|
DWORD dwResult = SignalObjectAndWait(hEvent, hEvent, 60000, FALSE);
|
|
if (dwResult == WAIT_OBJECT_0)
|
|
hr = S_OK;
|
|
else
|
|
/* If the resolver does not respond within 60 seconds, then another
|
|
* session got in just ahead of you...
|
|
*/
|
|
hr = E_ACCESSDENIED;
|
|
}
|
|
else
|
|
{
|
|
/* this is the call to the resolver that tells it we are now ready to begin RA */
|
|
SetEvent(hEvent);
|
|
hr = S_OK;
|
|
}
|
|
CloseHandle(hEvent);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
* Do nothing, as the script will kill the HelpCtr window
|
|
*/
|
|
hr = S_OK;
|
|
}
|
|
|
|
done:
|
|
// tell the ~dtor we don't need it to signal the resolver
|
|
m_boolResolverSignaled = TRUE;
|
|
return hr;
|
|
}
|
|
#endif
|