Leaked source code of windows server 2003
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.
 
 
 
 
 
 

595 lines
19 KiB

/******************************************************************************
Copyright (c) 2000 Microsoft Corporation
Module Name:
dllmain.cpp
Abstract:
Implementation of DLL Exports.
Revision History:
Davide Massarenti (Dmassare) 04/15/2000
created
******************************************************************************/
#include "stdafx.h"
CComModule _Module;
////////////////////////////////////////////////////////////////////////////////
HRESULT CreateObject_RemoteDesktopSession( /*[in] */ REMOTE_DESKTOP_SHARING_CLASS sharingClass ,
/*[in] */ long lTimeout ,
/*[in] */ BSTR bstrConnectionParms ,
/*[in] */ BSTR bstrUserHelpBlob ,
/*[out, retval]*/ ISAFRemoteDesktopSession* *ppRCS );
HRESULT ConnectToExpert(/* [in] */ BSTR bstrExpertConnectParm,
/* [in] */ LONG lTimeout,
/* [retval][out] */ LONG *lSafErrorCode);
HRESULT SwitchDesktopMode(/* [in]*/ int nMode,
/* [in]*/ int nRAType);
////////////////////////////////////////////////////////////////////////////////
#ifdef DEBUG
#define LAUNCH_TIMEOUT (600) // 1 minute.
#else
#define LAUNCH_TIMEOUT (300) // 10 seconds.
#endif
////////////////////////////////////////////////////////////////////////////////
static const CLSID* pCLSID_PCHUpdate = &__uuidof( PCHUpdate );
static const CLSID* pCLSID_PCHUpdateReal = &__uuidof( PCHUpdateReal );
static const CLSID* pCLSID_PCHService = &__uuidof( PCHService );
static const CLSID* pCLSID_PCHServiceReal = &__uuidof( PCHServiceReal );
#ifndef NOJETBLUECOM
static const CLSID* pCLSID_PCHDBSession = &__uuidof( PCHDBSession );
static const CLSID* pCLSID_PCHDBSessionReal = &__uuidof( PCHDBSessionReal );
#endif
static const CLSID* pCLSID_MPCConnection = &__uuidof( MPCConnection );
static const CLSID* pCLSID_MPCConnectionReal = &__uuidof( MPCConnectionReal );
static const CLSID* pCLSID_MPCUpload = &__uuidof( MPCUpload );
static const CLSID* pCLSID_MPCUploadReal = &__uuidof( MPCUploadReal );
static const IID* pIID_IPCHService = &__uuidof( IPCHService );
static const WCHAR s_szRegKey [] = L"SOFTWARE\\Microsoft\\PCHealth\\PchSvc\\Profile";
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
static const WCHAR s_szCmd_HelpSvc [] = L"\"%WINDIR%\\PCHealth\\HelpCtr\\Binaries\\HelpSvc.exe\" /Embedding";
static const WCHAR s_szCmd_UploadMgr [] = L"\"%WINDIR%\\PCHealth\\UploadLB\\Binaries\\UploadM.exe\" /Embedding";
static CComRedirectorFactory s_HelpSvc[] =
{
CComRedirectorFactory( pCLSID_PCHService, pCLSID_PCHServiceReal, pIID_IPCHService, s_szCmd_HelpSvc ),
CComRedirectorFactory( pCLSID_PCHUpdate , pCLSID_PCHUpdateReal , NULL , s_szCmd_HelpSvc ),
#ifndef NOJETBLUECOM
CComRedirectorFactory( pCLSID_PCHDBSession , pCLSID_PCHDBSessionReal , NULL , s_szCmd_HelpSvc ),
#endif
CComRedirectorFactory( NULL , NULL , NULL , NULL ),
};
static CComRedirectorFactory s_UploadMgr[] =
{
CComRedirectorFactory( pCLSID_MPCUpload , pCLSID_MPCUploadReal , NULL, s_szCmd_UploadMgr ),
CComRedirectorFactory( pCLSID_MPCConnection, pCLSID_MPCConnectionReal, NULL, s_szCmd_UploadMgr ),
CComRedirectorFactory( NULL , NULL , NULL, NULL ),
};
static ServiceHandler* s_Services[2];
////////////////////////////////////////////////////////////////////////////////
static const WCHAR s_szCmd_RDSHost [] = L"\"%WINDIR%\\system32\\RDSHOST.exe\"";
static CComRedirectorFactory g_RDSHost( NULL, &CLSID_SAFRemoteDesktopServerHost, &IID_ISAFRemoteDesktopServerHost, s_szCmd_RDSHost );
HRESULT RDSHost_HACKED_CreateInstance( LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj )
{
return g_RDSHost.CreateInstance( pUnkOuter, riid, ppvObj );
}
////////////////////////////////////////////////////////////////////////////////
CComRedirectorFactory::CComRedirectorFactory( const CLSID* pclsid ,
const CLSID* pclsidReal ,
const IID* piidDirecty ,
LPCWSTR szExecutable )
{
m_pclsid = pclsid;
m_pclsidReal = pclsidReal;
m_piidDirecty = piidDirecty;
m_szExecutable = szExecutable;
m_dwRegister = 0;
}
////////////////////
STDMETHODIMP_(ULONG) CComRedirectorFactory::AddRef()
{
return 1;
}
STDMETHODIMP_(ULONG) CComRedirectorFactory::Release()
{
return 1;
}
STDMETHODIMP CComRedirectorFactory::QueryInterface(REFIID iid, void ** ppvObject)
{
if(ppvObject == NULL) return E_POINTER;
*ppvObject = NULL;
if(InlineIsEqualGUID( IID_IUnknown , iid ) ||
InlineIsEqualGUID( IID_IClassFactory, iid ) )
{
*ppvObject = (IClassFactory*)this; // No AddRef, these objects are static...
return S_OK;
}
else if(InlineIsEqualGUID( IID_IDispatch , iid ) ||
InlineIsEqualGUID( IID_IPCHUtility, iid ) )
{
*ppvObject = (IPCHUtility*)this; // No AddRef, these objects are static...
return S_OK;
}
else if(m_piidDirecty && InlineIsEqualGUID( *m_piidDirecty, iid ))
{
return GetServer( NULL, iid, ppvObject );
}
return E_NOINTERFACE;
}
////////////////////
STDMETHODIMP CComRedirectorFactory::CreateInstance( LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj )
{
return StartServer( pUnkOuter, riid, ppvObj );
}
STDMETHODIMP CComRedirectorFactory::LockServer(BOOL fLock)
{
return S_OK;
}
////////////////////
STDMETHODIMP CComRedirectorFactory::CreateObject_RemoteDesktopSession( /*[in] */ REMOTE_DESKTOP_SHARING_CLASS sharingClass ,
/*[in] */ long lTimeout ,
/*[in] */ BSTR bstrConnectionParms ,
/*[in] */ BSTR bstrUserHelpBlob ,
/*[out, retval]*/ ISAFRemoteDesktopSession* *ppRCS )
{
return ::CreateObject_RemoteDesktopSession( sharingClass ,
lTimeout ,
bstrConnectionParms ,
bstrUserHelpBlob ,
ppRCS );
}
////////////////////
STDMETHODIMP CComRedirectorFactory::ConnectToExpert(/* [in] */ BSTR bstrExpertConnectParm,
/* [in] */ LONG lTimeout,
/* [retval][out] */ LONG *lSafErrorCode)
{
return ::ConnectToExpert( bstrExpertConnectParm,
lTimeout,
lSafErrorCode);
}
////////////////////
STDMETHODIMP CComRedirectorFactory::SwitchDesktopMode(/* [in]*/ int nMode,
/* [in]*/ int nRAType)
{
return ::SwitchDesktopMode(nMode, nRAType);
}
////////////////////
HRESULT CComRedirectorFactory::GetServer( LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj )
{
return ::CoCreateInstance( *m_pclsidReal, pUnkOuter, CLSCTX_LOCAL_SERVER, riid, ppvObj );
}
bool CComRedirectorFactory::GetCommandLine( /*[out]*/ WCHAR* rgCommandLine, /*[in]*/ DWORD dwSize, /*[out]*/ bool& fProfiling )
{
fProfiling = false;
//
// If there's a string value in the registry for this CLSID, prepend the command line with it.
//
{
WCHAR rgGUID[128];
if(::StringFromGUID2 ( *m_pclsid, rgGUID, MAXSTRLEN(rgGUID) ) > 0)
{
HKEY hKey;
if(::RegOpenKeyExW( HKEY_LOCAL_MACHINE, s_szRegKey, 0, KEY_READ, &hKey ) == ERROR_SUCCESS)
{
WCHAR rgVALUE[MAX_PATH*3];
DWORD dwVALUE = sizeof(rgVALUE)-1;
DWORD dwType;
if(::RegQueryValueExW( hKey, rgGUID, NULL, &dwType, (BYTE*)rgVALUE, &dwVALUE ) == ERROR_SUCCESS && dwType == REG_SZ)
{
rgVALUE[dwVALUE/sizeof(WCHAR)] = 0;
if((dwVALUE = ::ExpandEnvironmentStringsW( rgVALUE, rgCommandLine, dwSize )))
{
rgCommandLine[dwVALUE-1] = ' '; // Padding space.
rgCommandLine += dwVALUE;
dwSize -= dwVALUE;
fProfiling = true;
}
}
::RegCloseKey( hKey );
}
}
}
//
// Prepare the command line.
//
if(::ExpandEnvironmentStringsW( m_szExecutable, rgCommandLine, dwSize ))
{
return true;
}
return false;
}
HRESULT CComRedirectorFactory::StartServer( LPUNKNOWN pUnkOuter, REFIID riid, void** ppvObj )
{
HRESULT hr;
if(FAILED(hr = GetServer( pUnkOuter, riid, ppvObj )))
{
WCHAR rgCommandLine[MAX_PATH*3];
bool fProfiling;
::EnterCriticalSection( &m_sec );
//
// Prepare the command line.
//
if(GetCommandLine( rgCommandLine, MAXSTRLEN(rgCommandLine), fProfiling ))
{
PROCESS_INFORMATION piProcessInformation;
STARTUPINFOW siStartupInfo;
BOOL fStarted;
::ZeroMemory( (PVOID)&piProcessInformation, sizeof( piProcessInformation ) );
::ZeroMemory( (PVOID)&siStartupInfo , sizeof( siStartupInfo ) ); siStartupInfo.cb = sizeof( siStartupInfo );
//
// Start the process, changing the WinStation to the console one in case of profiling.
//
{
if(fProfiling)
{
// siStartupInfo.lpDesktop = L"WinSta0\\Default";
}
fStarted = ::CreateProcessW( NULL ,
rgCommandLine ,
NULL ,
NULL ,
FALSE ,
NORMAL_PRIORITY_CLASS ,
NULL ,
NULL ,
&siStartupInfo ,
&piProcessInformation );
}
if(fStarted)
{
int iCount = LAUNCH_TIMEOUT;
if(fProfiling) iCount *= 10; // Give more time to start.
while(iCount-- > 0)
{
if(::WaitForSingleObject( piProcessInformation.hProcess, 100 ) != WAIT_TIMEOUT) break; // Process bailed out.
if(SUCCEEDED(hr = GetServer( pUnkOuter, riid, ppvObj ))) break;
}
if(FAILED(hr))
{
::TerminateProcess( piProcessInformation.hProcess, 0 );
}
}
if(piProcessInformation.hProcess) ::CloseHandle( piProcessInformation.hProcess );
if(piProcessInformation.hThread ) ::CloseHandle( piProcessInformation.hThread );
}
::LeaveCriticalSection( &m_sec );
}
return hr;
}
HRESULT CComRedirectorFactory::Register()
{
::InitializeCriticalSection( &m_sec );
if(!m_pclsid) return S_OK;
return ::CoRegisterClassObject( *m_pclsid ,
(IClassFactory*)this ,
CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER ,
REGCLS_MULTIPLEUSE ,
&m_dwRegister );
}
void CComRedirectorFactory::Unregister()
{
if(m_dwRegister)
{
::CoRevokeClassObject( m_dwRegister );
m_dwRegister = 0;
}
::DeleteCriticalSection( &m_sec );
}
////////////////////////////////////////////////////////////////////////////////
ServiceHandler::ServiceHandler( /*[in]*/ LPCWSTR szServiceName, /*[in]*/ CComRedirectorFactory* rgClasses )
{
m_szServiceName = szServiceName; // LPCWSTR m_szServiceName;
m_rgClasses = rgClasses; // CComRedirectorFactory* m_rgClasses;
//
m_fComInitialized = false; // bool m_fComInitialized;
//
m_hShutdownEvent = NULL; // HANDLE m_hShutdownEvent;
//
// SERVICE_STATUS_HANDLE m_hServiceStatus;
// SERVICE_STATUS m_status;
::ZeroMemory( &m_status, sizeof( m_status ) );
m_status.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
m_status.dwCurrentState = SERVICE_STOPPED;
m_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
m_status.dwWin32ExitCode = 0;
m_status.dwServiceSpecificExitCode = 0;
m_status.dwCheckPoint = 0;
m_status.dwWaitHint = 0;
}
/////////////////////////////////////////////////////////////////////////////
// DLL Entry Point
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
if(dwReason == DLL_PROCESS_ATTACH)
{
_Module.Init( NULL, hInstance, NULL );
DisableThreadLibraryCalls( hInstance );
s_Services[0] = new ServiceHandler_HelpSvc( L"HelpSvc" , s_HelpSvc );
s_Services[1] = new ServiceHandler ( L"UploadMgr", s_UploadMgr );
g_RDSHost.Register();
}
else if(dwReason == DLL_PROCESS_DETACH)
{
delete s_Services[0];
delete s_Services[1];
g_RDSHost.Unregister();
_Module.Term();
}
return TRUE; // ok
}
DWORD WINAPI _HandlerEx( DWORD dwControl , // requested control code
DWORD dwEventType , // event type
LPVOID lpEventData , // event data
LPVOID lpContext ) // user-defined context data
{
ServiceHandler* handler = static_cast<ServiceHandler*>(lpContext);
return handler->HandlerEx( dwControl , // requested control code
dwEventType , // event type
lpEventData ); // user-defined context data
}
void WINAPI ServiceMain( DWORD dwArgc, LPWSTR* lpszArgv )
{
#if 0
BOOL fWait = true;
while(fWait)
{
Sleep(1000);
}
#endif
LPWSTR szName = lpszArgv[0];
ServiceHandler** ph = s_Services;
int i;
for(i=0; i<ARRAYSIZE(s_Services); i++)
{
ServiceHandler* h = *ph++;
if(h && !_wcsicmp( h->m_szServiceName, szName ))
{
h->Run(); break;
}
}
}
////////////////////////////////////////////////////////////////////////////////
DWORD ServiceHandler::HandlerEx( DWORD dwControl , // requested control code
DWORD dwEventType , // event type
LPVOID lpEventData ) // event data
{
switch(dwControl)
{
case SERVICE_CONTROL_STOP:
SetServiceStatus( SERVICE_STOP_PENDING );
if(m_hShutdownEvent) ::SetEvent( m_hShutdownEvent );
break;
case SERVICE_CONTROL_PAUSE:
break;
case SERVICE_CONTROL_CONTINUE:
break;
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_SHUTDOWN:
break;
default:
return ERROR_CALL_NOT_IMPLEMENTED;
}
return NO_ERROR;
}
HRESULT ServiceHandler::Initialize()
{
__MPC_FUNC_ENTRY( COMMONID, "ServiceHandler::Initialize" );
HRESULT hr;
m_status.dwWin32ExitCode = S_OK;
m_status.dwCheckPoint = 0;
m_status.dwWaitHint = 0;
try
{
CComRedirectorFactory* classes;
__MPC_EXIT_IF_CALL_RETURNS_NULL(hr, (m_hServiceStatus = ::RegisterServiceCtrlHandlerExW( m_szServiceName, _HandlerEx, this )));
SetServiceStatus( SERVICE_START_PENDING );
////////////////////
__MPC_EXIT_IF_METHOD_FAILS(hr, ::CoInitializeEx( NULL, COINIT_MULTITHREADED ));
m_fComInitialized = true;
for(classes=m_rgClasses; SUCCEEDED(hr) && classes->m_pclsid; classes++)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, classes->Register());
}
////////////////////
__MPC_EXIT_IF_CALL_RETURNS_NULL(hr, (m_hShutdownEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL )));
SetServiceStatus( SERVICE_RUNNING );
}
catch(...)
{
__MPC_SET_ERROR_AND_EXIT(hr, E_FAIL);
}
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr);
}
void ServiceHandler::WaitUntilStopped()
{
if(m_hShutdownEvent) ::WaitForSingleObject( m_hShutdownEvent, INFINITE );
}
void ServiceHandler::Cleanup()
{
if(m_hShutdownEvent)
{
::CloseHandle( m_hShutdownEvent );
m_hShutdownEvent = NULL;
}
try
{
if(m_fComInitialized)
{
CComRedirectorFactory* classes;
for(classes=m_rgClasses; classes->m_pclsid; classes++)
{
classes->Unregister();
}
::CoUninitialize();
m_fComInitialized = false;
}
}
catch(...)
{
}
if(m_hServiceStatus)
{
SetServiceStatus( SERVICE_STOPPED );
m_hServiceStatus = NULL;
}
}
void ServiceHandler::Run()
{
//
// When the Run function returns, the service has been stopped.
//
if(SUCCEEDED(Initialize()))
{
WaitUntilStopped();
}
Cleanup();
}
void ServiceHandler::SetServiceStatus( DWORD dwState )
{
m_status.dwCurrentState = dwState;
::SetServiceStatus( m_hServiceStatus, &m_status );
}